Go to the source code of this file.
Classes | |
struct | lwatch_path_info_t |
struct which mirrors one row from the watch database. More... | |
struct | database_iter_context_t |
Iteration context used to iterate over a set of lwatch_path_info_t structs returned by a watch database query. More... | |
Defines | |
#define | WATCH_DATABASE_ERROR_BASE -3500 |
Base error code (minimum value) for watch database errors. | |
#define | WATCH_DATABASE_ERROR_LIMIT (WATCH_DATABASE_ERROR_BASE + 50) |
Maximum error code for watch database errors. | |
#define | IS_WATCH_DATABASE_ERROR(error) (((error) >= WATCH_DATABASE_ERROR_BASE) && ((error) < WATCH_DATABASE_ERROR_LIMIT)) |
Return true if error code is within the range for watch database errors. | |
#define | WATCH_DATABASE_ERROR_CANNOT_OPEN (WATCH_DATABASE_ERROR_BASE + 1) |
could not open database | |
#define | WATCH_DATABASE_ERROR_CANNOT_CLOSE (WATCH_DATABASE_ERROR_BASE + 2) |
could not close database | |
#define | WATCH_DATABASE_ERROR_CANNOT_QUERY (WATCH_DATABASE_ERROR_BASE + 3) |
database query failed | |
#define | WATCH_DATABASE_ERROR_CANNOT_CREATE_TABLE (WATCH_DATABASE_ERROR_BASE + 4) |
cannot create table | |
#define | WATCH_DATABASE_ERROR_CANNOT_INSERT (WATCH_DATABASE_ERROR_BASE + 5) |
cannot insert record into table | |
#define | WATCH_DATABASE_ERROR_NOT_FOUND (WATCH_DATABASE_ERROR_BASE + 6) |
entry not found | |
#define | WATCH_DATABASE_ERROR_FOUND_MULTIPLE (WATCH_DATABASE_ERROR_BASE + 7) |
found multiple entries, expecting single entry | |
#define | WATCH_DATABASE_PATHNAME DATABASEDIR "/" PACKAGE_NAME ".db" |
The path name of the SQLite database used for lwatch. | |
#define | LWATCH_TABLE_NAME "lwatch" |
The name of the table where we persistently store lwatch_path_info_t data. | |
#define | PATH_INFO_FLAG_SET_TARGET(path_info) |
Update the flags to indicate this path is a watch target. | |
#define | PATH_INFO_FLAG_SET_BACKUP(path_info) |
Update the flags to indicate this path is a backup of a watch target. | |
#define | PATH_INFO_FLAG_SET_INC_VERSION(path_info) |
Update the flags to indicate this path needs to have it's version number incremented the next time. | |
#define | PATH_INFO_FLAG_SET_NEW_FILE(path_info) |
Update the flags to indicate this file has been lost and from this point forward we need to consider any reference to this file will represent new contents for the file. | |
Typedefs | |
typedef struct lwatch_path_info_t *(* | database_iter_next_t )(struct database_iter_context_t *iter) |
Pointer to function returning pointer to lwatch_path_info_t. | |
Enumerations | |
enum | path_info_flags_t { TARGET_FLAG = 0x0001, BACKUP_FLAG = 0x0002, NEEDS_REAPING_FLAG = 0x0004, STAT_DATA_VALID_FLAG = 0x0008, INC_VERSION_FLAG = 0x0010 } |
Boolean flags used to indicate path_info state. More... | |
Functions | |
int | init_path_info (struct lwatch_path_info_t *path_info, const char *path) |
Initialize a lwatch_path_info_t struct. | |
int | new_path_info (const char *path, struct lwatch_path_info_t **path_info_arg) |
Allocate and initialize a new lwatch_path_info_t struct. | |
char * | path_info_flags_string (unsigned long flag, const char *separator) |
Render the lwatch_path_info_t flag bitset as a string. | |
char * | path_info_string (struct lwatch_path_info_t *path_info, const char *prefix) |
Render a lwatch_path_info_t struct as a string. | |
int | watch_database_init (void) |
Initialize the watch database subsystem. | |
int | watch_database_fini (void) |
Close the watch database subsystem, release all resources, close database. | |
const char * | watch_database_error_string (int error) |
Render a database error code as a string. | |
int | database_lookup_path_info (const char *path, struct lwatch_path_info_t *path_info) |
Given a path name lookup the matching lwatch_path_info_t in the database. | |
int | database_write_path_info (struct lwatch_path_info_t *path_info) |
Write the supplied lwatch_path_info_t struct into the database. | |
int | database_query_all_paths_iter (struct database_iter_context_t **iter_arg, const char *path_filter_arg) |
Get an iterator to every lwatch_path_info_t row in the database. | |
int | database_query_backups_iter (struct database_iter_context_t **iter_arg) |
Get an iterator to every lwatch_path_info_t row in the database which is a backup to a primary file. | |
int | database_query_backups_of_target_iter (struct database_iter_context_t **iter_arg, const char *path) |
Get an iterator to each lwatch_path_info_t row in the database which is a backup to the specified primary file. | |
int | database_query_pending_reaps_iter (struct database_iter_context_t **iter_arg) |
Get an iterator to every lwatch_path_info_t row which has a reap pending. | |
int | database_query_targets_iter (struct database_iter_context_t **iter_arg) |
Get an iterator to every lwatch_path_info_t row which is a primary watch file, i.e. |
Definition in file watch_database.h.
#define IS_WATCH_DATABASE_ERROR | ( | error | ) | (((error) >= WATCH_DATABASE_ERROR_BASE) && ((error) < WATCH_DATABASE_ERROR_LIMIT)) |
Return true if error code is within the range for watch database errors.
[in] | error | The error code to test if it's a watch database error code. |
Definition at line 35 of file watch_database.h.
Referenced by error_string().
#define PATH_INFO_FLAG_SET_BACKUP | ( | path_info | ) |
Value:
{ \ (path_info)->flags |= BACKUP_FLAG; \ (path_info)->flags &= ~(TARGET_FLAG | INC_VERSION_FLAG); \ }
Definition at line 66 of file watch_database.h.
Referenced by process_file_rename().
#define PATH_INFO_FLAG_SET_INC_VERSION | ( | path_info | ) |
Value:
{ \ if (!((path_info)->flags & BACKUP_FLAG)) \ (path_info)->flags |= INC_VERSION_FLAG; \ }
This occurs when we detect a file has had it's contents replaced and is now a new file, hence it will have a higher version number.
Definition at line 78 of file watch_database.h.
#define PATH_INFO_FLAG_SET_NEW_FILE | ( | path_info | ) |
Value:
{ \ PATH_INFO_FLAG_SET_INC_VERSION(path_info); \ (path_info)->flags &= ~(STAT_DATA_VALID_FLAG | NEEDS_REAPING_FLAG); \ }
Definition at line 89 of file watch_database.h.
Referenced by process_file_delete(), and process_file_rename().
#define PATH_INFO_FLAG_SET_TARGET | ( | path_info | ) |
Value:
{ \ (path_info)->flags |= TARGET_FLAG; \ (path_info)->flags &= ~BACKUP_FLAG; \ }
Definition at line 57 of file watch_database.h.
Referenced by start_monitoring().
enum path_info_flags_t |
Boolean flags used to indicate path_info state.
Definition at line 102 of file watch_database.h.
00102 { 00103 TARGET_FLAG = 0x0001, /**< true if this path is a primary watch target */ 00104 BACKUP_FLAG = 0x0002, /**< true if this path is backup of a primary watch target */ 00105 NEEDS_REAPING_FLAG = 0x0004, /**< true if contents of this file needs to be collected (e.g. reaped) */ 00106 STAT_DATA_VALID_FLAG = 0x0008, /**< true if stat information is valid */ 00107 INC_VERSION_FLAG = 0x0010, /**< true if we need to increment the version number on the primary watch 00108 target because the file was replaced */ 00109 } path_info_flags_t;
int database_lookup_path_info | ( | const char * | path, | |
struct lwatch_path_info_t * | path_info | |||
) |
Given a path name lookup the matching lwatch_path_info_t in the database.
[in] | path | Path Name whose lwatch_path_info_t we seek |
[out] | path_info | Pointer to lwatch_path_info_t which will be initialized from the database upon success. |
Definition at line 968 of file watch_database.c.
Referenced by get_create_path_info(), process_file_close(), process_file_create(), process_file_delete(), process_file_modification(), and process_file_rename().
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 }
int database_query_all_paths_iter | ( | struct database_iter_context_t ** | iter_arg, | |
const char * | path_filter_arg | |||
) |
Get an iterator to every lwatch_path_info_t row in the database.
[out] | iter_arg | Iterator context returned here, NULL if failure |
[in] | path_filter_arg | SQL "like" wildcard pattern, path must match this pattern to be included in result set. If NULL then no filtering is performed, all paths will match. |
Definition at line 1028 of file watch_database.c.
Referenced by dump_database().
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 }
int database_query_backups_iter | ( | struct database_iter_context_t ** | iter_arg | ) |
Get an iterator to every lwatch_path_info_t row in the database which is a backup to a primary file.
[out] | iter_arg | Iterator context returned here, NULL if failure |
Definition at line 1070 of file watch_database.c.
Referenced by validate_backups_in_database().
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 }
int database_query_backups_of_target_iter | ( | struct database_iter_context_t ** | iter_arg, | |
const char * | path | |||
) |
Get an iterator to each lwatch_path_info_t row in the database which is a backup to the specified primary file.
[out] | iter_arg | Iterator context returned here, NULL if failure |
[in] | path | The path name of the primary file whose backup's are sought |
Definition at line 1100 of file watch_database.c.
Referenced by dump_database().
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 }
int database_query_pending_reaps_iter | ( | struct database_iter_context_t ** | iter_arg | ) |
Get an iterator to every lwatch_path_info_t row which has a reap pending.
[out] | iter_arg | Iterator context returned here, NULL if failure |
Definition at line 1135 of file watch_database.c.
Referenced by process_pending_reaps().
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 }
int database_query_targets_iter | ( | struct database_iter_context_t ** | iter_arg | ) |
Get an iterator to every lwatch_path_info_t row which is a primary watch file, i.e.
a "target".
[out] | iter_arg | Iterator context returned here, NULL if failure |
Definition at line 1164 of file watch_database.c.
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 }
int database_write_path_info | ( | struct lwatch_path_info_t * | path_info | ) |
Write the supplied lwatch_path_info_t struct into the database.
[in] | path_info | The lwatch_path_info_t to write into the database |
Definition at line 523 of file watch_database.c.
Referenced by get_create_path_info(), process_file_close(), process_file_delete(), process_file_modification(), process_file_rename(), reap_file_data(), start_monitoring(), update_stat_info_and_write(), and validate_backups_in_database().
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 }
int init_path_info | ( | struct lwatch_path_info_t * | path_info, | |
const char * | path | |||
) |
Initialize a lwatch_path_info_t struct.
[in] | path_info | The lwatch_path_info_t to initialize |
[in] | path | The path name bound to the lwatch_path_info_t |
Definition at line 596 of file watch_database.c.
Referenced by get_create_path_info(), and new_path_info().
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 }
int new_path_info | ( | const char * | path, | |
struct lwatch_path_info_t ** | path_info_arg | |||
) |
Allocate and initialize a new lwatch_path_info_t struct.
[in] | path | The path name which will be bound to the lwatch_path_info_t |
[in] | path_info_arg | Pointer to variable to receive pointer to new path_info |
Definition at line 622 of file watch_database.c.
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 }
char* path_info_flags_string | ( | unsigned long | flag, | |
const char * | separator | |||
) |
Render the lwatch_path_info_t flag bitset as a string.
[in] | flag | The bitset whose boolean flags will be converted to strings |
[in] | separator | The string used to separate adjacent flags |
Definition at line 652 of file watch_database.c.
Referenced by path_info_string().
00653 { 00654 static __thread char buf[1024]; /* thread local static buffer */ 00655 char *p, *buf_end; 00656 int separator_len; 00657 unsigned int unknown; 00658 00659 p = buf; /* current position in buffer */ 00660 buf_end = &buf[sizeof(buf)]; /* non-inclusive end of buffer */ 00661 separator_len = strlen(separator); 00662 *p = 0; 00663 00664 /* validate there is nothing in the event mask we don't know about */ 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; /* nuke trailing separator */ 00683 00684 return buf; 00685 00686 fail: 00687 /* exhausted the buffer; NULL terminate then return truncated string */ 00688 buf_end[-1] = 0; /* should already be NULL terminated, but be safe */ 00689 return buf; 00690 }
char* path_info_string | ( | struct lwatch_path_info_t * | path_info, | |
const char * | prefix | |||
) |
Render a lwatch_path_info_t struct as a string.
[in] | path_info | The lwatch_path_info_t struct to convert to a string |
[in] | prefix | String prepended to each line in the output |
Definition at line 702 of file watch_database.c.
Referenced by dump_database().
00703 { 00704 static __thread char buf[1024]; /* thread local static buffer */ 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; /* current position in buffer */ 00719 buf_end = &buf[sizeof(buf)]; /* non-inclusive end of buffer */ 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 /* exhausted the buffer; NULL terminate then return truncated string */ 00808 buf_end[-1] = 0; /* should already be NULL terminated, but be safe */ 00809 free(uid_name); 00810 free(gid_name); 00811 return buf; 00812 }
const char* watch_database_error_string | ( | int | error | ) |
Render a database error code as a string.
[in] | error | The database error code to convert to a string |
Definition at line 820 of file watch_database.c.
Referenced by error_string().
00821 { 00822 static __thread char buf[80]; /* thread local static buffer */ 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 }
int watch_database_fini | ( | void | ) |
Close the watch database subsystem, release all resources, close database.
Definition at line 935 of file watch_database.c.
Referenced by main().
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 }
int watch_database_init | ( | void | ) |
Initialize the watch database subsystem.
Definition at line 850 of file watch_database.c.
Referenced by main().
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 /* Create prepared SQL statements for master table */ 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 /* Assure our table exists, if not create it */ 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 /* Create prepared SQL statements for our table */ 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 }