00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #define _GNU_SOURCE
00015 #include <stdio.h>
00016 #include <stdlib.h>
00017 #include <stdarg.h>
00018 #include <stdint.h>
00019 #include <string.h>
00020 #include <errno.h>
00021
00022 #include <sys/types.h>
00023 #include <sys/param.h>
00024 #include <unistd.h>
00025 #include <sqlite3.h>
00026
00027 #include "config.h"
00028 #include "util.h"
00029 #include "logging.h"
00030 #include "watch_database.h"
00031 #include "path_utils.h"
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #define COLUMNS_STRING "path, original_path, flags, version, reap_time, reap_position, dev, inode, mode, uid, gid, size, access_time, modification_time, change_time"
00042
00043
00044
00045
00046
00047 #define PATH_COLUMN 0
00048 #define ORIGINAL_PATH_COLUMN 1
00049 #define FLAGS_COLUMN 2
00050 #define VERSION_COLUMN 3
00051 #define REAP_TIME_COLUMN 4
00052 #define REAP_POSITION_COLUMN 5
00053 #define DEV_COLUMN 6
00054 #define INODE_COLUMN 7
00055 #define MODE_COLUMN 8
00056 #define UID_COLUMN 9
00057 #define GID_COLUMN 10
00058 #define SIZE_COLUMN 11
00059 #define ACCESS_TIME_COLUMN 12
00060 #define MODIFICATION_TIME_COLUMN 13
00061 #define CHANGE_TIME_COLUMN 14
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079 struct path_info_iter_context_t {
00080 struct database_iter_context_t iter;
00081 sqlite3_stmt *stmt;
00082 int step_result;
00083 struct lwatch_path_info_t path_info;
00084
00085 };
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095 static const char *sqlite3_result_string(int result);
00096 static int table_exists(const char *table_name, bool *exists);
00097 static int create_table(const char *table_name, const char *table_schema);
00098 static int populate_path_info(struct lwatch_path_info_t *path_info, sqlite3_stmt *stmt);
00099 static struct lwatch_path_info_t *path_info_iter_next(struct path_info_iter_context_t *iter);
00100 static int new_path_info_iter_context(struct path_info_iter_context_t **iter_arg);
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 static const char *lwatch_table_schema =
00114 "path TEXT PRIMARY KEY,\n\
00115 original_path TEXT,\n\
00116 flags INTEGER,\n\
00117 version INTEGER,\n\
00118 reap_time INTEGER,\n\
00119 reap_position INTEGER,\n\
00120 dev INTEGER,\n\
00121 inode INTEGER,\n\
00122 mode INTEGER,\n\
00123 uid INTEGER,\n\
00124 gid INTEGER,\n\
00125 size INTEGER,\n\
00126 access_time INTEGER,\n\
00127 modification_time INTEGER,\n\
00128 change_time INTEGER\n\
00129 ";
00130
00131
00132
00133
00134 static char watch_database_pathname[PATH_MAX] = WATCH_DATABASE_PATHNAME;
00135
00136
00137
00138 static sqlite3 *database_handle = NULL;
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150 sqlite3_stmt *table_exists_stmt = NULL;
00151
00152
00153
00154 sqlite3_stmt *lookup_path_stmt = NULL;
00155
00156
00157
00158 sqlite3_stmt *insert_path_stmt = NULL;
00159
00160
00161
00162 sqlite3_stmt *query_all_stmt = NULL;
00163
00164
00165
00166 sqlite3_stmt *query_backups_stmt = NULL;
00167
00168
00169
00170 sqlite3_stmt *query_backups_of_target_stmt = NULL;
00171
00172
00173
00174 sqlite3_stmt *query_pending_reaps_stmt = NULL;
00175
00176
00177
00178 sqlite3_stmt *query_targets_stmt = NULL;
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203 static int init_statement(struct sqlite3_stmt **stmt_arg, const char *fmt, ...)
00204 {
00205 va_list ap;
00206 int error;
00207 sqlite3_stmt *stmt;
00208 char *sql;
00209
00210 va_start(ap, fmt);
00211 vasprintf(&sql, fmt, ap);
00212
00213 if ((error = sqlite3_prepare_v2(database_handle, sql, -1, &stmt, NULL)) != SQLITE_OK) {
00214 const char *err_msg = sqlite3_errmsg(database_handle);
00215 log_msg(LOG_ERROR, _("could not prepare statement \"%s\", (%s)\n"), sql, err_msg);
00216 free(sql);
00217 *stmt_arg = NULL;
00218 return WATCH_DATABASE_ERROR_CANNOT_QUERY;
00219 }
00220
00221 free(sql);
00222 *stmt_arg = stmt;
00223 return SUCCESS;
00224 }
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236 static int destroy_statement(sqlite3_stmt **stmt_arg)
00237 {
00238 int error;
00239 sqlite3_stmt *stmt;
00240
00241 if ((stmt = *stmt_arg) == NULL) return SUCCESS;
00242
00243 if ((error = sqlite3_finalize(stmt)) != SQLITE_OK) {
00244 const char *err_msg = sqlite3_errmsg(database_handle);
00245 log_msg(LOG_ERROR, _("sqlite3_finalize (%s)\n"), err_msg);
00246 return error;
00247 }
00248 *stmt_arg = NULL;
00249 return SUCCESS;
00250 }
00251
00252
00253
00254
00255
00256
00257
00258 static int reset_statement(sqlite3_stmt *stmt)
00259 {
00260 int error;
00261
00262 if ((error = sqlite3_reset(stmt)) != SQLITE_OK) {
00263 const char *err_msg = sqlite3_errmsg(database_handle);
00264 log_msg(LOG_ERROR, _("sqlite3_reset \"%s\", (%s)\n"), sqlite3_sql(stmt), err_msg);
00265 return WATCH_DATABASE_ERROR_CANNOT_QUERY;
00266 }
00267 return SUCCESS;
00268 }
00269
00270
00271
00272
00273
00274
00275
00276 static const char *sqlite3_result_string(int result)
00277 {
00278 static __thread char buf[64];
00279
00280 switch(result) {
00281 case SQLITE_OK: return "SQLITE_OK";
00282 case SQLITE_ERROR: return "SQLITE_ERROR";
00283 case SQLITE_INTERNAL: return "SQLITE_INTERNAL";
00284 case SQLITE_PERM: return "SQLITE_PERM";
00285 case SQLITE_ABORT: return "SQLITE_ABORT";
00286 case SQLITE_BUSY: return "SQLITE_BUSY";
00287 case SQLITE_LOCKED: return "SQLITE_LOCKED";
00288 case SQLITE_NOMEM: return "SQLITE_NOMEM";
00289 case SQLITE_READONLY: return "SQLITE_READONLY";
00290 case SQLITE_INTERRUPT: return "SQLITE_INTERRUPT";
00291 case SQLITE_IOERR: return "SQLITE_IOERR";
00292 case SQLITE_CORRUPT: return "SQLITE_CORRUPT";
00293 case SQLITE_NOTFOUND: return "SQLITE_NOTFOUND";
00294 case SQLITE_FULL: return "SQLITE_FULL";
00295 case SQLITE_CANTOPEN: return "SQLITE_CANTOPEN";
00296 case SQLITE_PROTOCOL: return "SQLITE_PROTOCOL";
00297 case SQLITE_EMPTY: return "SQLITE_EMPTY";
00298 case SQLITE_SCHEMA: return "SQLITE_SCHEMA";
00299 case SQLITE_TOOBIG: return "SQLITE_TOOBIG";
00300 case SQLITE_CONSTRAINT: return "SQLITE_CONSTRAINT";
00301 case SQLITE_MISMATCH: return "SQLITE_MISMATCH";
00302 case SQLITE_MISUSE: return "SQLITE_MISUSE";
00303 case SQLITE_NOLFS: return "SQLITE_NOLFS";
00304 case SQLITE_AUTH: return "SQLITE_AUTH";
00305 case SQLITE_FORMAT: return "SQLITE_FORMAT";
00306 case SQLITE_RANGE: return "SQLITE_RANGE";
00307 case SQLITE_NOTADB: return "SQLITE_NOTADB";
00308 case SQLITE_ROW: return "SQLITE_ROW";
00309 case SQLITE_DONE: return "SQLITE_DONE";
00310
00311 case SQLITE_IOERR_READ: return "SQLITE_IOERR_READ";
00312 case SQLITE_IOERR_SHORT_READ: return "SQLITE_IOERR_SHORT_READ";
00313 case SQLITE_IOERR_WRITE: return "SQLITE_IOERR_WRITE";
00314 case SQLITE_IOERR_FSYNC: return "SQLITE_IOERR_FSYNC";
00315 case SQLITE_IOERR_DIR_FSYNC: return "SQLITE_IOERR_DIR_FSYNC";
00316 case SQLITE_IOERR_TRUNCATE: return "SQLITE_IOERR_TRUNCATE";
00317 case SQLITE_IOERR_FSTAT: return "SQLITE_IOERR_FSTAT";
00318 case SQLITE_IOERR_UNLOCK: return "SQLITE_IOERR_UNLOCK";
00319 case SQLITE_IOERR_RDLOCK: return "SQLITE_IOERR_RDLOCK";
00320 case SQLITE_IOERR_DELETE: return "SQLITE_IOERR_DELETE";
00321 case SQLITE_IOERR_BLOCKED: return "SQLITE_IOERR_BLOCKED";
00322 case SQLITE_IOERR_NOMEM: return "SQLITE_IOERR_NOMEM";
00323 default:
00324 snprintf(buf, sizeof(buf), "unknown(%d)", result);
00325 return buf;
00326 }
00327 }
00328
00329
00330
00331
00332
00333
00334
00335
00336 static int table_exists(const char *table_name, bool *exists)
00337 {
00338 int error, result, step_result, row_count;
00339 const char *name;
00340
00341 result = SUCCESS;
00342 *exists = false;
00343
00344 if ((error = reset_statement(table_exists_stmt)) != SUCCESS) {
00345 result = WATCH_DATABASE_ERROR_CANNOT_QUERY;
00346 goto exit;
00347 }
00348
00349 if ((error = sqlite3_bind_text(table_exists_stmt, 1, table_name, -1, SQLITE_TRANSIENT)) != SQLITE_OK) {
00350 const char *err_msg = sqlite3_errmsg(database_handle);
00351 log_msg(LOG_ERROR, _("sqlite3_bind_text \"%s\", (%s)\n"), sqlite3_sql(table_exists_stmt), err_msg);
00352 result = WATCH_DATABASE_ERROR_CANNOT_QUERY;
00353 goto exit;
00354 }
00355
00356 row_count = 0;
00357 while(true) {
00358 step_result = sqlite3_step(table_exists_stmt);
00359 if (step_result == SQLITE_DONE) {
00360 break;
00361 } else if (step_result == SQLITE_ROW) {
00362 row_count++;
00363 name = (const char *)sqlite3_column_text(table_exists_stmt, 0);
00364 *exists = strcmp(name, table_name) == 0 ? true : false;
00365 } else {
00366 const char *err_msg = sqlite3_errmsg(database_handle);
00367 log_msg(LOG_ERROR, _("sqlite3_step \"%s\", unexpected result %s (%s)\n"),
00368 sqlite3_sql(table_exists_stmt), sqlite3_result_string(step_result), err_msg);
00369 result = WATCH_DATABASE_ERROR_CANNOT_QUERY;
00370 }
00371 }
00372
00373 if (row_count > 1) {
00374 log_msg(LOG_ERROR, _("\"%s\", unexpected multiple rows (%d) returned\n"),
00375 sqlite3_sql(table_exists_stmt), row_count);
00376 result = WATCH_DATABASE_ERROR_FOUND_MULTIPLE;
00377 }
00378
00379 exit:
00380 return result;
00381 }
00382
00383
00384
00385
00386
00387
00388
00389
00390 static int create_table(const char *table_name, const char *table_schema)
00391 {
00392 int result, sql_result;
00393 char *statement;
00394 char *err_msg;
00395
00396 result = SUCCESS;
00397
00398 if (asprintf(&statement, "create table %s (%s);", table_name, table_schema) < 0) {
00399 log_msg(LOG_ERROR, _("cannot create statement string\n"));
00400 return ENOMEM;
00401 }
00402
00403 if ((sql_result = sqlite3_exec(database_handle, statement, NULL, NULL, &err_msg)) != SQLITE_OK) {
00404 log_msg(LOG_ERROR, _("sqlite3_exec \"%s\", failed with error %d (%s)\n"), statement, sql_result, err_msg);
00405 sqlite3_free(err_msg);
00406 result = WATCH_DATABASE_ERROR_CANNOT_CREATE_TABLE;
00407 }
00408
00409 free(statement);
00410
00411 return result;
00412 }
00413
00414
00415
00416
00417
00418
00419
00420
00421 int populate_path_info(struct lwatch_path_info_t *path_info, sqlite3_stmt *stmt)
00422 {
00423 int error;
00424
00425 if ((error = copy_path(path_info->path, (const char *)sqlite3_column_text(stmt, PATH_COLUMN),
00426 sizeof(path_info->path))) != SUCCESS) {
00427 log_msg(LOG_ERROR, _("failed to copy path \"%s\" (%s)\n"), (const char *)sqlite3_column_text(stmt, 0), error_string(error));
00428 return error;
00429 }
00430 if ((error = copy_path(path_info->original_path, (const char *)sqlite3_column_text(stmt, ORIGINAL_PATH_COLUMN),
00431 sizeof(path_info->original_path))) != SUCCESS) {
00432 log_msg(LOG_ERROR, _("failed to copy path \"%s\" (%s)\n"), (const char *)sqlite3_column_text(stmt, 1), error_string(error));
00433 return error;
00434 }
00435
00436 path_info->flags = sqlite3_column_int64(stmt, FLAGS_COLUMN);
00437 path_info->version = sqlite3_column_int64(stmt, VERSION_COLUMN);
00438 path_info->reap_time = sqlite3_column_int64(stmt, REAP_TIME_COLUMN);
00439 path_info->reap_position = sqlite3_column_int64(stmt, REAP_POSITION_COLUMN);
00440 path_info->dev = sqlite3_column_int64(stmt, DEV_COLUMN);
00441 path_info->inode = sqlite3_column_int64(stmt, INODE_COLUMN);
00442 path_info->mode = sqlite3_column_int64(stmt, MODE_COLUMN);
00443 path_info->uid = sqlite3_column_int64(stmt, UID_COLUMN);
00444 path_info->gid = sqlite3_column_int64(stmt, GID_COLUMN);
00445 path_info->size = sqlite3_column_int64(stmt, SIZE_COLUMN);
00446 path_info->access_time = sqlite3_column_int64(stmt, ACCESS_TIME_COLUMN);
00447 path_info->modification_time = sqlite3_column_int64(stmt, MODIFICATION_TIME_COLUMN);
00448 path_info->change_time = sqlite3_column_int64(stmt, CHANGE_TIME_COLUMN);
00449
00450 return SUCCESS;
00451 }
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469 static struct lwatch_path_info_t *path_info_iter_next(struct path_info_iter_context_t *iter)
00470 {
00471 iter->iter.error = SUCCESS;
00472
00473 iter->step_result = sqlite3_step(iter->stmt);
00474 if (iter->step_result == SQLITE_DONE) {
00475 return NULL;
00476 } else if (iter->step_result == SQLITE_ROW) {
00477 populate_path_info(&iter->path_info, iter->stmt);
00478 return &iter->path_info;
00479 } else {
00480 const char *err_msg = sqlite3_errmsg(database_handle);
00481 log_msg(LOG_ERROR, _("sqlite3_step \"%s\", unexpected result %s (%s)\n"),
00482 sqlite3_sql(iter->stmt), sqlite3_result_string(iter->step_result), err_msg);
00483 iter->iter.error = WATCH_DATABASE_ERROR_CANNOT_QUERY;
00484 return NULL;
00485 }
00486 }
00487
00488
00489
00490
00491
00492
00493
00494 static int new_path_info_iter_context(struct path_info_iter_context_t **iter_arg)
00495 {
00496 struct path_info_iter_context_t *iter;
00497
00498 *iter_arg = NULL;
00499 if ((iter = malloc(sizeof(struct path_info_iter_context_t))) == NULL) {
00500 return ENOMEM;
00501 }
00502
00503 iter->iter.next = (database_iter_next_t) path_info_iter_next;
00504 iter->iter.error = SUCCESS;
00505
00506 iter->stmt = NULL;
00507 iter->step_result = SQLITE_OK;
00508
00509 *iter_arg = iter;
00510 return SUCCESS;
00511 }
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523 int database_write_path_info(struct lwatch_path_info_t *path_info)
00524 {
00525 int error, result, step_result;
00526
00527 result = SUCCESS;
00528
00529 if ((error = reset_statement(insert_path_stmt)) != SUCCESS) {
00530 result = WATCH_DATABASE_ERROR_CANNOT_QUERY;
00531 goto exit;
00532 }
00533
00534
00535 if ((error = sqlite3_bind_text(insert_path_stmt, PATH_COLUMN + 1, path_info->path, -1, SQLITE_TRANSIENT))
00536 != SQLITE_OK) goto bind_error;
00537 if ((error = sqlite3_bind_text(insert_path_stmt, ORIGINAL_PATH_COLUMN + 1, path_info->original_path, -1, SQLITE_TRANSIENT))
00538 != SQLITE_OK) goto bind_error;
00539 if ((error = sqlite3_bind_int64(insert_path_stmt, FLAGS_COLUMN + 1, path_info->flags))
00540 != SQLITE_OK) goto bind_error;
00541 if ((error = sqlite3_bind_int64(insert_path_stmt, VERSION_COLUMN + 1, path_info->version))
00542 != SQLITE_OK) goto bind_error;
00543 if ((error = sqlite3_bind_int64(insert_path_stmt, REAP_TIME_COLUMN + 1, path_info->reap_time))
00544 != SQLITE_OK) goto bind_error;
00545 if ((error = sqlite3_bind_int64(insert_path_stmt, REAP_POSITION_COLUMN + 1, path_info->reap_position))
00546 != SQLITE_OK) goto bind_error;
00547 if ((error = sqlite3_bind_int64(insert_path_stmt, DEV_COLUMN + 1, path_info->dev))
00548 != SQLITE_OK) goto bind_error;
00549 if ((error = sqlite3_bind_int64(insert_path_stmt, INODE_COLUMN + 1, path_info->inode))
00550 != SQLITE_OK) goto bind_error;
00551 if ((error = sqlite3_bind_int64(insert_path_stmt, MODE_COLUMN + 1, path_info->mode))
00552 != SQLITE_OK) goto bind_error;
00553 if ((error = sqlite3_bind_int64(insert_path_stmt, UID_COLUMN + 1, path_info->uid))
00554 != SQLITE_OK) goto bind_error;
00555 if ((error = sqlite3_bind_int64(insert_path_stmt, GID_COLUMN + 1, path_info->gid))
00556 != SQLITE_OK) goto bind_error;
00557 if ((error = sqlite3_bind_int64(insert_path_stmt, SIZE_COLUMN + 1, path_info->size))
00558 != SQLITE_OK) goto bind_error;
00559 if ((error = sqlite3_bind_int64(insert_path_stmt, ACCESS_TIME_COLUMN + 1, path_info->access_time))
00560 != SQLITE_OK) goto bind_error;
00561 if ((error = sqlite3_bind_int64(insert_path_stmt, MODIFICATION_TIME_COLUMN + 1, path_info->modification_time))
00562 != SQLITE_OK) goto bind_error;
00563 if ((error = sqlite3_bind_int64(insert_path_stmt, CHANGE_TIME_COLUMN + 1, path_info->change_time))
00564 != SQLITE_OK) goto bind_error;
00565
00566 if ((step_result = sqlite3_step(insert_path_stmt)) != SQLITE_DONE) {
00567 const char *err_msg = sqlite3_errmsg(database_handle);
00568 log_msg(LOG_ERROR, _("sqlite3_step \"%s\", unexpected result %s (%s)\n"),
00569 sqlite3_sql(insert_path_stmt), sqlite3_result_string(step_result), err_msg);
00570 result = WATCH_DATABASE_ERROR_CANNOT_INSERT;
00571 goto exit;
00572 }
00573
00574 exit:
00575 return result;
00576
00577 bind_error: {
00578 const char *err_msg = sqlite3_errmsg(database_handle);
00579 log_msg(LOG_ERROR, _("sqlite3_bind_text \"%s\", (%s)\n"), sqlite3_sql(insert_path_stmt), err_msg);
00580 result = WATCH_DATABASE_ERROR_CANNOT_QUERY;
00581 return result;
00582 }
00583 }
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596 int init_path_info(struct lwatch_path_info_t *path_info, const char *path)
00597 {
00598 int error;
00599
00600 memset(path_info, 0, sizeof(struct lwatch_path_info_t));
00601
00602 if (path) {
00603 if ((error = copy_path(path_info->path, path, sizeof(path_info->path))) != SUCCESS) {
00604 log_msg(LOG_ERROR, _("failed to copy path \"%s\" (%s)\n"), path, error_string(error));
00605 return error;
00606 }
00607 }
00608
00609 path_info->flags = INC_VERSION_FLAG;
00610 return SUCCESS;
00611 }
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622 int new_path_info(const char *path, struct lwatch_path_info_t **path_info_arg)
00623 {
00624 int error;
00625 struct lwatch_path_info_t *path_info;
00626
00627 if ((path_info = malloc(sizeof(struct lwatch_path_info_t))) == NULL) {
00628 return ENOMEM;
00629 }
00630
00631 if ((error = init_path_info(path_info, path)) != SUCCESS) {
00632 log_msg(LOG_ERROR, _("could not initialize path_info for path \"%s\" (%s)\n"),
00633 path, error_string(error));
00634 free(path_info);
00635 return error;
00636 }
00637
00638 *path_info_arg = path_info;
00639 return SUCCESS;
00640 }
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652 char *path_info_flags_string(unsigned long flag, const char *separator)
00653 {
00654 static __thread char buf[1024];
00655 char *p, *buf_end;
00656 int separator_len;
00657 unsigned int unknown;
00658
00659 p = buf;
00660 buf_end = &buf[sizeof(buf)];
00661 separator_len = strlen(separator);
00662 *p = 0;
00663
00664
00665 unknown = flag & ~(TARGET_FLAG | BACKUP_FLAG | NEEDS_REAPING_FLAG |
00666 STAT_DATA_VALID_FLAG | INC_VERSION_FLAG);
00667
00668 if (unknown) p += snprintf(p, buf_end - p, "unknown bits=0x%x%s", unknown, separator);
00669 if (p >= buf_end) goto fail;
00670
00671 if (flag & TARGET_FLAG) p += snprintf(p, buf_end - p, "TARGET%s", separator);
00672 if (p >= buf_end) goto fail;
00673 if (flag & BACKUP_FLAG) p += snprintf(p, buf_end - p, "BACKUP%s", separator);
00674 if (p >= buf_end) goto fail;
00675 if (flag & NEEDS_REAPING_FLAG) p += snprintf(p, buf_end - p, "NEEDS_REAPING%s", separator);
00676 if (p >= buf_end) goto fail;
00677 if (flag & STAT_DATA_VALID_FLAG) p += snprintf(p, buf_end - p, "STAT_DATA_VALID%s", separator);
00678 if (p >= buf_end) goto fail;
00679 if (flag & INC_VERSION_FLAG) p += snprintf(p, buf_end - p, "INC_VERSION%s", separator);
00680 if (p >= buf_end) goto fail;
00681
00682 if (p > buf) p[-separator_len] = 0;
00683
00684 return buf;
00685
00686 fail:
00687
00688 buf_end[-1] = 0;
00689 return buf;
00690 }
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702 char *path_info_string(struct lwatch_path_info_t *path_info, const char *prefix)
00703 {
00704 static __thread char buf[1024];
00705 const char *indent = " ";
00706 char prefix_indent[128];
00707 char *p, *buf_end;
00708 char *uid_name, *gid_name;
00709
00710 strncpy(prefix_indent, prefix, sizeof(prefix_indent));
00711 prefix_indent[sizeof(prefix_indent) - 1] = 0;
00712 strncat(prefix_indent, indent, sizeof(prefix_indent) - 1);
00713
00714 get_uid_name(path_info->uid, &uid_name);
00715 get_gid_name(path_info->gid, &gid_name);
00716
00717
00718 p = buf;
00719 buf_end = &buf[sizeof(buf)];
00720 *p = 0;
00721
00722 p += snprintf(p, buf_end - p, "%spath: %s\n",
00723 prefix, path_info->path);
00724 if (p >= buf_end) goto fail;
00725
00726 if (path_info->original_path[0]) {
00727 p += snprintf(p, buf_end - p, "%soriginal path: %s\n",
00728 prefix_indent,
00729 path_info->original_path);
00730 if (p >= buf_end) goto fail;
00731 }
00732
00733 p += snprintf(p, buf_end - p, "%sflags: [%s]\n",
00734 prefix_indent,
00735 path_info_flags_string(path_info->flags, ","));
00736 if (p >= buf_end) goto fail;
00737
00738 p += snprintf(p, buf_end - p, "%sversion: %lu\n",
00739 prefix_indent,
00740 path_info->version);
00741 if (p >= buf_end) goto fail;
00742
00743 p += snprintf(p, buf_end - p, "%sreap_time: %s (%ld)\n",
00744 prefix_indent,
00745 time_string(path_info->reap_time, true, NULL),
00746 path_info->reap_time);
00747 if (p >= buf_end) goto fail;
00748
00749 p += snprintf(p, buf_end - p, "%sreap_position: %ld\n",
00750 prefix_indent,
00751 path_info->reap_position);
00752 if (p >= buf_end) goto fail;
00753
00754 if (path_info->flags & STAT_DATA_VALID_FLAG) {
00755 p += snprintf(p, buf_end - p, "%sdev: %llu\n",
00756 prefix_indent,
00757 path_info->dev);
00758 if (p >= buf_end) goto fail;
00759
00760 p += snprintf(p, buf_end - p, "%sinode: %lu\n",
00761 prefix_indent,
00762 path_info->inode);
00763 if (p >= buf_end) goto fail;
00764
00765 p += snprintf(p, buf_end - p, "%smode: %s (%#o)\n",
00766 prefix_indent,
00767 file_mode_string(path_info->mode),
00768 path_info->mode);
00769 if (p >= buf_end) goto fail;
00770
00771 p += snprintf(p, buf_end - p, "%suid:gid: %s:%s (%u:%u)\n",
00772 prefix_indent,
00773 uid_name, gid_name,
00774 path_info->uid, path_info->gid);
00775 if (p >= buf_end) goto fail;
00776
00777 p += snprintf(p, buf_end - p, "%ssize: %ld\n",
00778 prefix_indent,
00779 path_info->size);
00780 if (p >= buf_end) goto fail;
00781
00782 p += snprintf(p, buf_end - p, "%saccess_time: %s (%ld)\n",
00783 prefix_indent,
00784 time_string(path_info->access_time, true, NULL),
00785 path_info->access_time);
00786 if (p >= buf_end) goto fail;
00787
00788 p += snprintf(p, buf_end - p, "%smodification time: %s (%ld)\n",
00789 prefix_indent,
00790 time_string(path_info->modification_time, true, NULL),
00791 path_info->modification_time);
00792 if (p >= buf_end) goto fail;
00793
00794 p += snprintf(p, buf_end - p, "%schange_time: %s (%ld)\n",
00795 prefix_indent,
00796 time_string(path_info->change_time, true, NULL),
00797 path_info->change_time);
00798 if (p >= buf_end) goto fail;
00799 }
00800
00801
00802 free(uid_name);
00803 free(gid_name);
00804 return buf;
00805
00806 fail:
00807
00808 buf_end[-1] = 0;
00809 free(uid_name);
00810 free(gid_name);
00811 return buf;
00812 }
00813
00814
00815
00816
00817
00818
00819
00820 const char *watch_database_error_string(int error)
00821 {
00822 static __thread char buf[80];
00823
00824 switch(error) {
00825 case SUCCESS: return _("success");
00826 case WATCH_DATABASE_ERROR_CANNOT_OPEN: return _("could not open database");
00827 case WATCH_DATABASE_ERROR_CANNOT_CLOSE: return _("could not close database");
00828 case WATCH_DATABASE_ERROR_CANNOT_QUERY: return _("database query failed");
00829 case WATCH_DATABASE_ERROR_CANNOT_CREATE_TABLE: return _("cannot create table");
00830 case WATCH_DATABASE_ERROR_CANNOT_INSERT: return _("cannot insert record into table");
00831 case WATCH_DATABASE_ERROR_NOT_FOUND: return _("entry not found");
00832 case WATCH_DATABASE_ERROR_FOUND_MULTIPLE: return _("found multiple entries, expecting single entry");
00833 default:
00834 snprintf(buf, sizeof(buf), _("unknown(%d)"), error);
00835 return buf;
00836 }
00837 }
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850 int watch_database_init()
00851 {
00852 int error;
00853 bool exists;
00854
00855 if ((error = sqlite3_open(watch_database_pathname, &database_handle)) != SQLITE_OK) {
00856 const char *err_msg = sqlite3_errmsg(database_handle);
00857 log_msg(LOG_ERROR, _("could not open database file \"%s\", (%s)\n"),watch_database_pathname, err_msg);
00858 sqlite3_close(database_handle);
00859 database_handle = NULL;
00860 return WATCH_DATABASE_ERROR_CANNOT_OPEN;
00861 }
00862
00863
00864 if ((error = init_statement(&table_exists_stmt,
00865 "SELECT name FROM sqlite_master WHERE type='table' AND name=?1;")) != SUCCESS) {
00866 return error;
00867 }
00868
00869
00870 if ((error = table_exists(LWATCH_TABLE_NAME, &exists)) != SUCCESS) {
00871 log_msg(LOG_ERROR, _("table_exists failed \"%s\" (%s)\n"), LWATCH_TABLE_NAME, error_string(error));
00872 return WATCH_DATABASE_ERROR_CANNOT_QUERY;
00873 }
00874
00875 if (!exists) {
00876 if ((error = create_table(LWATCH_TABLE_NAME, lwatch_table_schema)) != SUCCESS) {
00877 log_msg(LOG_ERROR, _("\"%s\" table does not exist, but failed to create (%s)\n"),
00878 LWATCH_TABLE_NAME, error_string(error));
00879 return error;
00880 }
00881 }
00882
00883
00884 if ((error = init_statement(&lookup_path_stmt,
00885 "SELECT %s FROM \"%s\" WHERE path=?1;",
00886 COLUMNS_STRING, LWATCH_TABLE_NAME)) != SUCCESS) {
00887 return WATCH_DATABASE_ERROR_CANNOT_QUERY;
00888 }
00889
00890 if ((error = init_statement(&insert_path_stmt,
00891 "INSERT OR REPLACE INTO \"%s\" (%s) VALUES "
00892 "(?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15);",
00893 LWATCH_TABLE_NAME, COLUMNS_STRING)) != SUCCESS) {
00894 return WATCH_DATABASE_ERROR_CANNOT_QUERY;
00895 }
00896
00897 if ((error = init_statement(&query_all_stmt,
00898 "SELECT %s FROM \"%s\" where path like ?1;",
00899 COLUMNS_STRING, LWATCH_TABLE_NAME)) != SUCCESS) {
00900 return WATCH_DATABASE_ERROR_CANNOT_QUERY;
00901 }
00902
00903 if ((error = init_statement(&query_backups_stmt,
00904 "SELECT %s FROM \"%s\" where flags & %d;",
00905 COLUMNS_STRING, LWATCH_TABLE_NAME, BACKUP_FLAG)) != SUCCESS) {
00906 return WATCH_DATABASE_ERROR_CANNOT_QUERY;
00907 }
00908
00909 if ((error = init_statement(&query_backups_of_target_stmt,
00910 "SELECT %s FROM \"%s\" where flags & %d AND original_path == ?1;",
00911 COLUMNS_STRING, LWATCH_TABLE_NAME, BACKUP_FLAG)) != SUCCESS) {
00912 return WATCH_DATABASE_ERROR_CANNOT_QUERY;
00913 }
00914
00915 if ((error = init_statement(&query_pending_reaps_stmt,
00916 "SELECT %s FROM \"%s\" where flags & %d;",
00917 COLUMNS_STRING, LWATCH_TABLE_NAME, NEEDS_REAPING_FLAG)) != SUCCESS) {
00918 return WATCH_DATABASE_ERROR_CANNOT_QUERY;
00919 }
00920
00921 if ((error = init_statement(&query_targets_stmt,
00922 "SELECT %s FROM \"%s\" where flags & %d;",
00923 COLUMNS_STRING, LWATCH_TABLE_NAME, TARGET_FLAG)) != SUCCESS) {
00924 return WATCH_DATABASE_ERROR_CANNOT_QUERY;
00925 }
00926
00927 return SUCCESS;
00928 }
00929
00930
00931
00932
00933
00934
00935 int watch_database_fini()
00936 {
00937 int error;
00938
00939 destroy_statement(&table_exists_stmt);
00940 destroy_statement(&lookup_path_stmt);
00941 destroy_statement(&insert_path_stmt);
00942 destroy_statement(&query_all_stmt);
00943 destroy_statement(&query_backups_stmt);
00944 destroy_statement(&query_backups_of_target_stmt);
00945 destroy_statement(&query_pending_reaps_stmt);
00946 destroy_statement(&query_targets_stmt);
00947
00948 if ((error = sqlite3_close(database_handle)) != SQLITE_OK) {
00949 const char *err_msg = sqlite3_errmsg(database_handle);
00950 log_msg(LOG_ERROR, _("could not close database file \"%s\", (%s)\n"), watch_database_pathname, err_msg);
00951 database_handle = NULL;
00952 return WATCH_DATABASE_ERROR_CANNOT_CLOSE;
00953 }
00954 database_handle = NULL;
00955 return SUCCESS;
00956 }
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968 int database_lookup_path_info(const char *path, struct lwatch_path_info_t *path_info)
00969 {
00970 int error, result, step_result;
00971 int n_rows;
00972
00973 result = SUCCESS;
00974
00975 if ((error = reset_statement(lookup_path_stmt)) != SUCCESS) {
00976 result = WATCH_DATABASE_ERROR_CANNOT_QUERY;
00977 goto exit;
00978 }
00979
00980 if ((error = sqlite3_bind_text(lookup_path_stmt, 1, path, -1, SQLITE_TRANSIENT)) != SQLITE_OK) {
00981 const char *err_msg = sqlite3_errmsg(database_handle);
00982 log_msg(LOG_ERROR, _("sqlite3_bind_text \"%s\", (%s)\n"), sqlite3_sql(lookup_path_stmt), err_msg);
00983 result = WATCH_DATABASE_ERROR_CANNOT_QUERY;
00984 goto exit;
00985 }
00986
00987 n_rows = 0;
00988 while(true) {
00989 step_result = sqlite3_step(lookup_path_stmt);
00990 if (step_result == SQLITE_DONE) {
00991 break;
00992 } else if (step_result == SQLITE_ROW) {
00993 if (n_rows == 0) {
00994 if ((error = populate_path_info(path_info, lookup_path_stmt)) != SUCCESS) {
00995 log_msg(LOG_ERROR, _("populate_path_info() failed for path \"%s\" (%s)"),
00996 path, error_string(error));
00997 result = error;
00998 }
00999 }
01000 n_rows++;
01001 } else {
01002 const char *err_msg = sqlite3_errmsg(database_handle);
01003 log_msg(LOG_ERROR, _("sqlite3_step \"%s\", unexpected result %s (%s)\n"),
01004 sqlite3_sql(lookup_path_stmt), sqlite3_result_string(step_result), err_msg);
01005 }
01006 }
01007
01008 exit:
01009 if (result == SUCCESS) {
01010 if (n_rows == 0)
01011 result = WATCH_DATABASE_ERROR_NOT_FOUND;
01012 else if (n_rows > 1)
01013 result = WATCH_DATABASE_ERROR_FOUND_MULTIPLE;
01014 }
01015 return result;
01016 }
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028 int database_query_all_paths_iter(struct database_iter_context_t **iter_arg, const char *path_filter_arg)
01029 {
01030 int error;
01031 struct path_info_iter_context_t *iter;
01032 const char *path_filter;
01033
01034 *iter_arg = NULL;
01035 if ((error = new_path_info_iter_context(&iter)) != SUCCESS) {
01036 log_msg(LOG_ERROR, _("cannot allocate new iteration context (%s)\n"), error_string(error));
01037 return error;
01038 }
01039
01040 iter->stmt = query_all_stmt;
01041
01042 if ((iter->iter.error = reset_statement(iter->stmt)) != SQLITE_OK) {
01043 free(iter);
01044 return WATCH_DATABASE_ERROR_CANNOT_QUERY;
01045 }
01046
01047 if (path_filter_arg == NULL)
01048 path_filter = "%";
01049 else
01050 path_filter = path_filter_arg;
01051
01052 if ((iter->iter.error = sqlite3_bind_text(iter->stmt, 1, path_filter, -1, SQLITE_TRANSIENT)) != SQLITE_OK) {
01053 const char *err_msg = sqlite3_errmsg(database_handle);
01054 log_msg(LOG_ERROR, _("sqlite3_bind_text \"%s\", (%s)\n"), sqlite3_sql(iter->stmt), err_msg);
01055 free(iter);
01056 return WATCH_DATABASE_ERROR_CANNOT_QUERY;
01057 }
01058
01059 *iter_arg = (struct database_iter_context_t *)iter;
01060 return SUCCESS;
01061 }
01062
01063
01064
01065
01066
01067
01068
01069
01070 int database_query_backups_iter(struct database_iter_context_t **iter_arg)
01071 {
01072 int error;
01073 struct path_info_iter_context_t *iter;
01074
01075 *iter_arg = NULL;
01076 if ((error = new_path_info_iter_context(&iter)) != SUCCESS) {
01077 log_msg(LOG_ERROR, _("cannot allocate new iteration context (%s)\n"), error_string(error));
01078 return error;
01079 }
01080
01081 iter->stmt = query_backups_stmt;
01082
01083 if ((iter->iter.error = reset_statement(iter->stmt)) != SQLITE_OK) {
01084 free(iter);
01085 return WATCH_DATABASE_ERROR_CANNOT_QUERY;
01086 }
01087
01088 *iter_arg = (struct database_iter_context_t *)iter;
01089 return SUCCESS;
01090 }
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100 int database_query_backups_of_target_iter(struct database_iter_context_t **iter_arg, const char *path)
01101 {
01102 int error;
01103 struct path_info_iter_context_t *iter;
01104
01105 *iter_arg = NULL;
01106 if ((error = new_path_info_iter_context(&iter)) != SUCCESS) {
01107 log_msg(LOG_ERROR, _("cannot allocate new iteration context (%s)\n"), error_string(error));
01108 return error;
01109 }
01110
01111 iter->stmt = query_backups_of_target_stmt;
01112
01113 if ((iter->iter.error = reset_statement(iter->stmt)) != SQLITE_OK) {
01114 free(iter);
01115 return WATCH_DATABASE_ERROR_CANNOT_QUERY;
01116 }
01117
01118 if ((iter->iter.error = sqlite3_bind_text(iter->stmt, 1, path, -1, SQLITE_TRANSIENT)) != SQLITE_OK) {
01119 const char *err_msg = sqlite3_errmsg(database_handle);
01120 log_msg(LOG_ERROR, _("sqlite3_bind_text \"%s\", (%s)\n"), sqlite3_sql(iter->stmt), err_msg);
01121 free(iter);
01122 return WATCH_DATABASE_ERROR_CANNOT_QUERY;
01123 }
01124
01125 *iter_arg = (struct database_iter_context_t *)iter;
01126 return SUCCESS;
01127 }
01128
01129
01130
01131
01132
01133
01134
01135 int database_query_pending_reaps_iter(struct database_iter_context_t **iter_arg)
01136 {
01137 int error;
01138 struct path_info_iter_context_t *iter;
01139
01140 *iter_arg = NULL;
01141 if ((error = new_path_info_iter_context(&iter)) != SUCCESS) {
01142 log_msg(LOG_ERROR, _("cannot allocate new iteration context (%s)\n"), error_string(error));
01143 return error;
01144 }
01145
01146 iter->stmt = query_pending_reaps_stmt;
01147
01148 if ((iter->iter.error = reset_statement(iter->stmt)) != SQLITE_OK) {
01149 free(iter);
01150 return WATCH_DATABASE_ERROR_CANNOT_QUERY;
01151 }
01152
01153 *iter_arg = (struct database_iter_context_t *)iter;
01154 return SUCCESS;
01155 }
01156
01157
01158
01159
01160
01161
01162
01163
01164 int database_query_targets_iter(struct database_iter_context_t **iter_arg)
01165 {
01166 int error;
01167 struct path_info_iter_context_t *iter;
01168
01169 *iter_arg = NULL;
01170 if ((error = new_path_info_iter_context(&iter)) != SUCCESS) {
01171 log_msg(LOG_ERROR, _("cannot allocate new iteration context (%s)\n"), error_string(error));
01172 return error;
01173 }
01174
01175 iter->stmt = query_targets_stmt;
01176
01177 if ((iter->iter.error = reset_statement(iter->stmt)) != SQLITE_OK) {
01178 free(iter);
01179 return WATCH_DATABASE_ERROR_CANNOT_QUERY;
01180 }
01181
01182 *iter_arg = (struct database_iter_context_t *)iter;
01183 return SUCCESS;
01184 }
01185
01186