4 * Copyright (c) 2007, 2010 Oracle and/or its affiliates. All rights reserved.
5 * Use is subject to license terms.
7 * Author: Vladimir Saviliev <vladimir.saviliev@sun.com>
8 * Andreas Dilger <adilger@sun.com>
11 * This file may be redistributed under the terms of the
12 * GNU General Public License version 2.
16 #define _FILE_OFFSET_BITS 64
22 #include <ext2fs/ext2fs.h>
25 #if defined(HAVE_SQLITE3) && defined(HAVE_SQLITE3_H)
30 extern ext2_filsys fs;
40 /* number of files newer than specified time */
42 /* number of files reported */
43 ext2_ino_t nr_reported;
50 int block_iterate_cb(ext2_filsys fs, blk_t *block_nr,
52 blk_t ref_block EXT2FS_ATTR((unused)),
53 int ref_offset EXT2FS_ATTR((unused)),
57 static long count = 10000;
59 static void exec_one_sql_noreturn(sqlite3 *db, char *sqls)
63 if (sqlite3_exec(db, sqls, NULL, NULL, &errmsg) != SQLITE_OK) {
64 fprintf(stderr, "SQL error: %s;\nrequest: %s", errmsg, sqls);
70 static void create_sql_table(sqlite3 *db, const char *table_name,
75 if (asprintf(&sqls, "create table %s (%s)", table_name, columns) < 0) {
76 perror("asprintf failed");
80 exec_one_sql_noreturn(db, sqls);
84 static void begin_one_transaction(sqlite3 *db)
86 exec_one_sql_noreturn(db, "BEGIN;");
89 static void commit_one_transaction(sqlite3 *db)
91 exec_one_sql_noreturn(db, "COMMIT;");
94 static void batch_one_transaction(sqlite3 *db)
99 if (num % count == 0) {
100 commit_one_transaction(db);
101 begin_one_transaction(db);
103 /* else do nothing */
106 #define COLUMNS "ino, generation, parent, name, size, mtime, ctime, dtime"
108 static void create_full_db(const char *name, int fd)
115 if (sqlite3_open(name, &db) != SQLITE_OK) {
116 fprintf(stderr, "failed to sqlite3_open: %s\n", name);
120 create_sql_table(db, "dirs", COLUMNS);
121 create_sql_table(db, "files", COLUMNS);
123 begin_one_transaction(db);
127 rd = read(fd, sqls, 512);
129 perror("read failed\n");
135 exec_one_sql_noreturn(db, sqls);
136 batch_one_transaction(db);
138 commit_one_transaction(db);
139 printf("database is created, %d records are inserted\n", nr);
143 /* write sql command to pipe */
144 #define PIPECMDLEN 512
145 static void write_sql_command(int fd, const char *sqls)
147 char buf[PIPECMDLEN];
149 if (strlen(sqls) + 1 > PIPECMDLEN) {
150 fprintf(stderr, "too long command");
154 if (write(fd, buf, PIPECMDLEN) != PIPECMDLEN) {
155 perror("failed to write to pipe");
158 scan_data.db.nr_commands ++;
161 pid_t fork_db_creation(const char *database)
167 if (stat(database, &st) == 0) {
168 fprintf(stderr, "%s exists. remove it first\n", database);
172 fprintf(stderr, "failed to pipe");
177 if (pid == (pid_t)-1) {
178 fprintf(stderr, "failed to fork");
181 if (pid == (pid_t)0) {
182 /* child, read data written by parent and write to
185 create_full_db(database, p[0]);
190 /* parent, read inodes and write them to pipe */
192 scan_data.db.fd = p[1];
196 void database_iscan_action(ext2_ino_t ino, struct ext2_inode *inode,
201 if (LINUX_S_ISDIR(inode->i_mode)) {
202 if (ino == EXT2_ROOT_INO) {
203 sqls = sqlite3_mprintf("%s (%u,%u,%u,'%q',%u,%u,%u,%u)",
204 "insert into dirs values",
205 ino, inode->i_generation, ino, "/",
206 inode->i_size, inode->i_mtime,
207 inode->i_ctime, inode->i_dtime);
208 write_sql_command(fd, sqls);
212 if (ext2fs_block_iterate2(fs, ino, 0, buf,
213 block_iterate_cb, &ino)) {
214 fprintf(stderr, "ext2fs_block_iterate2 failed\n");
221 * callback for ext2fs_dblist_dir_iterate to be called for each
224 int database_dblist_iterate_cb(ext2_ino_t dir, struct ext2_dir_entry *dirent,
227 struct ext2_inode inode;
233 if (!ext2fs_fast_test_inode_bitmap2(fs->inode_map, dirent->inode))
234 /* entry of deleted file? can that ever happen */
237 retval = ext2fs_read_inode(fs, dirent->inode, &inode);
239 com_err("ext2fs_read_inode", retval, "while reading inode");
243 if (LINUX_S_ISDIR(inode.i_mode))
248 sprintf(str, "%.*s", namelen, dirent->name);
249 sqls = sqlite3_mprintf("%s %s %s (%u,%u,%u,'%q',%u,%u,%u,%u)",
250 "insert into", table, "values",
251 dirent->inode, inode.i_generation, dir,
253 inode.i_size, inode.i_mtime,
254 inode.i_ctime, inode.i_dtime);
255 write_sql_command(fd, sqls);
263 pid_t fork_db_creation(const char *database)
268 void database_iscan_action(ext2_ino_t ino, struct ext2_inode *inode,
274 int database_dblist_iterate_cb(ext2_ino_t dir, struct ext2_dir_entry *dirent,