00001 #ifndef WATCH_DATABASE_H 00002 #define WATCH_DATABASE_H 00003 00004 /*****************************************************************************/ 00005 /******************************** Documentation ******************************/ 00006 /*****************************************************************************/ 00007 00008 /** 00009 * \file 00010 * Public interface for using the watch database persistent store. 00011 */ 00012 00013 /*****************************************************************************/ 00014 /******************************* Include Files *******************************/ 00015 /*****************************************************************************/ 00016 00017 /*****************************************************************************/ 00018 /*********************************** Defines *********************************/ 00019 /*****************************************************************************/ 00020 00021 /** 00022 * Base error code (minimum value) for watch database errors 00023 */ 00024 #define WATCH_DATABASE_ERROR_BASE -3500 00025 /** 00026 * Maximum error code for watch database errors 00027 */ 00028 #define WATCH_DATABASE_ERROR_LIMIT (WATCH_DATABASE_ERROR_BASE + 50) 00029 /** 00030 * Return true if error code is within the range for watch database errors. 00031 * 00032 * \param[in] error The error code to test if it's a watch database error code. 00033 * \return True if error code is a watch database error. 00034 */ 00035 #define IS_WATCH_DATABASE_ERROR(error) (((error) >= WATCH_DATABASE_ERROR_BASE) && ((error) < WATCH_DATABASE_ERROR_LIMIT)) 00036 00037 #define WATCH_DATABASE_ERROR_CANNOT_OPEN (WATCH_DATABASE_ERROR_BASE + 1) /**< could not open database */ 00038 #define WATCH_DATABASE_ERROR_CANNOT_CLOSE (WATCH_DATABASE_ERROR_BASE + 2) /**< could not close database */ 00039 #define WATCH_DATABASE_ERROR_CANNOT_QUERY (WATCH_DATABASE_ERROR_BASE + 3) /**< database query failed */ 00040 #define WATCH_DATABASE_ERROR_CANNOT_CREATE_TABLE (WATCH_DATABASE_ERROR_BASE + 4) /**< cannot create table */ 00041 #define WATCH_DATABASE_ERROR_CANNOT_INSERT (WATCH_DATABASE_ERROR_BASE + 5) /**< cannot insert record into table */ 00042 #define WATCH_DATABASE_ERROR_NOT_FOUND (WATCH_DATABASE_ERROR_BASE + 6) /**< entry not found */ 00043 #define WATCH_DATABASE_ERROR_FOUND_MULTIPLE (WATCH_DATABASE_ERROR_BASE + 7) /**< found multiple entries, expecting single entry */ 00044 00045 /** 00046 * The path name of the SQLite database used for lwatch. 00047 */ 00048 #define WATCH_DATABASE_PATHNAME DATABASEDIR "/" PACKAGE_NAME ".db" 00049 /** 00050 * The name of the table where we persistently store lwatch_path_info_t data. 00051 */ 00052 #define LWATCH_TABLE_NAME "lwatch" 00053 00054 /** 00055 * Update the flags to indicate this path is a watch target. 00056 */ 00057 #define PATH_INFO_FLAG_SET_TARGET(path_info) \ 00058 { \ 00059 (path_info)->flags |= TARGET_FLAG; \ 00060 (path_info)->flags &= ~BACKUP_FLAG; \ 00061 } 00062 00063 /** 00064 * Update the flags to indicate this path is a backup of a watch target. 00065 */ 00066 #define PATH_INFO_FLAG_SET_BACKUP(path_info) \ 00067 { \ 00068 (path_info)->flags |= BACKUP_FLAG; \ 00069 (path_info)->flags &= ~(TARGET_FLAG | INC_VERSION_FLAG); \ 00070 } 00071 00072 /** 00073 * Update the flags to indicate this path needs to have it's version number 00074 * incremented the next time. This occurs when we detect a file has had it's 00075 * contents replaced and is now a new file, hence it will have a higher 00076 * version number. 00077 */ 00078 #define PATH_INFO_FLAG_SET_INC_VERSION(path_info) \ 00079 { \ 00080 if (!((path_info)->flags & BACKUP_FLAG)) \ 00081 (path_info)->flags |= INC_VERSION_FLAG; \ 00082 } 00083 00084 /** 00085 * Update the flags to indicate this file has been lost and from this point 00086 * forward we need to consider any reference to this file will represent new 00087 * contents for the file. 00088 */ 00089 #define PATH_INFO_FLAG_SET_NEW_FILE(path_info) \ 00090 { \ 00091 PATH_INFO_FLAG_SET_INC_VERSION(path_info); \ 00092 (path_info)->flags &= ~(STAT_DATA_VALID_FLAG | NEEDS_REAPING_FLAG); \ 00093 } 00094 00095 /*****************************************************************************/ 00096 /******************************* Type Definitions ****************************/ 00097 /*****************************************************************************/ 00098 00099 /** 00100 * Boolean flags used to indicate path_info state. 00101 */ 00102 typedef enum { 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; 00110 00111 /** 00112 * struct which mirrors one row from the watch database. 00113 */ 00114 struct lwatch_path_info_t { 00115 char path[PATH_MAX]; /**< path name */ 00116 char original_path[PATH_MAX]; /**< if this is a backup (rotated) file this is 00117 the path name it was derived from */ 00118 unsigned long flags; /**< path_info_flags_t boolean flags used to indicate state */ 00119 unsigned long version; /**< each time file is recreated this number incremented */ 00120 time_t reap_time; /**< time when file contents last reaped (collected) */ 00121 off_t reap_position; /**< file position where next reap should begin */ 00122 dev_t dev; /**< device number */ 00123 ino_t inode; /**< inode number */ 00124 mode_t mode; /**< file mode bit set */ 00125 uid_t uid; /**< user ID of owner */ 00126 gid_t gid; /**< group ID of owner */ 00127 off_t size; /**< total size, in bytes */ 00128 time_t access_time; /**< time of last access (e.g.: read) */ 00129 time_t modification_time; /**< time of last modification (file contents modified) */ 00130 time_t change_time; /**< time of last change (file contents modified) */ 00131 }; 00132 00133 struct database_iter_context_t; 00134 /** 00135 * Pointer to function returning pointer to lwatch_path_info_t 00136 */ 00137 typedef struct lwatch_path_info_t *(*database_iter_next_t)(struct database_iter_context_t *iter); 00138 /** 00139 * Iteration context used to iterate over a set of lwatch_path_info_t structs 00140 * returned by a watch database query. 00141 * 00142 * Example: 00143 * \code 00144 * struct database_iter_context_t *path_iter; 00145 * struct lwatch_path_info_t *path_info; 00146 * 00147 * if ((error = database_query_all_paths_iter(&path_iter, NULL)) != SUCCESS) { 00148 * // handle error 00149 * } 00150 * 00151 * while ((path_info = path_iter->next(path_iter))) { 00152 * // use path_info 00153 * } 00154 * \endcode 00155 */ 00156 struct database_iter_context_t { 00157 database_iter_next_t next; /**< pointer to function returning pointer to lwatch_path_info_t */ 00158 int error; /**< error code from query */ 00159 }; 00160 00161 /*****************************************************************************/ 00162 /************************* External Global Variables ***********************/ 00163 /*****************************************************************************/ 00164 00165 /*****************************************************************************/ 00166 /**************************** Exported Functions ***************************/ 00167 /*****************************************************************************/ 00168 00169 int init_path_info(struct lwatch_path_info_t *path_info, const char *path); 00170 int new_path_info(const char *path, struct lwatch_path_info_t **path_info_arg); 00171 char *path_info_flags_string(unsigned long flag, const char *separator); 00172 char *path_info_string(struct lwatch_path_info_t *path_info, const char *prefix); 00173 int watch_database_init(void); 00174 int watch_database_fini(void); 00175 const char *watch_database_error_string(int error); 00176 int database_lookup_path_info(const char *path, struct lwatch_path_info_t *path_info); 00177 int database_write_path_info(struct lwatch_path_info_t *path_info); 00178 int database_query_all_paths_iter(struct database_iter_context_t **iter_arg, const char *path_filter_arg); 00179 int database_query_backups_iter(struct database_iter_context_t **iter_arg); 00180 int database_query_backups_of_target_iter(struct database_iter_context_t **iter_arg, const char *path); 00181 int database_query_pending_reaps_iter(struct database_iter_context_t **iter_arg); 00182 int database_query_targets_iter(struct database_iter_context_t **iter_arg); 00183 00184 #endif