1 /* $Id: xtail.h,v 2.7 2000/06/04 19:02:23 chip Exp $ */ 2 3 4 /***************************************************************************** 5 * 6 * Start of Site-Specific Customizations 7 * 8 *****************************************************************************/ 9 10 /* 11 * STATUS_ENAB - If defined, a SIGINT causes a summary of the opened files to 12 * be displayed, and a SIGQUIT terminates the program. If not defined, 13 * these signals act normally. 14 */ 15 #define STATUS_ENAB 16 17 /* 18 * SLEEP_TIME - Number of seconds between iterations of the checking loop. 19 */ 20 #define SLEEP_TIME 1 21 22 /* 23 * CHECK_COUNT - Recently modified files are checked for changes every time 24 * through the checking loop. We only go looking for changes to 25 * not-so-recently modified stuff only once ever CHECK_COUNT iterations 26 * through the loop. 27 */ 28 #define CHECK_COUNT 5 29 30 /* 31 * MAX_OPEN - This number of most recently changed files is kept open, and 32 * they are checked every iteration through the checking loop. Keeping these 33 * files open improves the performance because we can use "fstat()" rather 34 * than "stat()". Keeping too many files open may overflow your open file 35 * table, and will reduce performance by checking more files more frequently. 36 */ 37 #define MAX_OPEN 8 38 39 /* 40 * MAX_ENTRIES - This is *BOGUS* I should get rid of this. 41 */ 42 #define MAX_ENTRIES 512 43 44 45 46 /***************************************************************************** 47 * 48 * End of Site-Specific Customizations 49 * 50 *****************************************************************************/ 51 52 53 #define TRUE 1 54 #define FALSE 0 55 56 #define Dprintf if ( !Debug ) ; else (void) fprintf 57 58 59 /* 60 * Codes returned by the "stat_entry()" procedure. 61 */ 62 #define ENTRY_ERROR 0 /* stat error or permissions error */ 63 #define ENTRY_SPECIAL 1 /* entry is a special file */ 64 #define ENTRY_FILE 2 /* entry is a regular file */ 65 #define ENTRY_DIR 3 /* entry is a directory */ 66 #define ENTRY_ZAP 4 /* specified entry doesn't exist */ 67 68 69 /* 70 * Diagnostic message codes. 71 * The ordering of codes must correspond to the "mssg_list[]" defined below. 72 */ 73 #define MSSG_NONE 0 /* no message - just reset header */ 74 #define MSSG_BANNER 1 /* display banner for file output */ 75 #define MSSG_CREATED 2 /* file has been created */ 76 #define MSSG_ZAPPED 3 /* file has been deleted */ 77 #define MSSG_TRUNC 4 /* file has been truncated */ 78 #define MSSG_NOTAFIL 5 /* error - not a regular file or dir */ 79 #define MSSG_STAT 6 /* error - stat() failed */ 80 #define MSSG_OPEN 7 /* error - open() failed */ 81 #define MSSG_SEEK 8 /* error - lseek() failed */ 82 #define MSSG_READ 9 /* error - read() failed */ 83 #define MSSG_UNKNOWN 10 /* unknown error - must be last in list */ 84 85 86 #ifdef INTERN 87 # define EXTERN 88 #else 89 # define EXTERN extern 90 #endif 91 92 93 /* 94 * Each item we are watching is stored in a (struct entry_descrip). These 95 * entries are placed in lists, which are managed as (struct entry_list). 96 * 97 * There are three lists maintained: 98 * 99 * List_file All of the regular files we are watching. We will try to 100 * keep the MAX_OPEN most recently modified files open, and 101 * they will be checked more frequently. 102 * 103 * List_dir All of the directories we are watching. If a file is created 104 * in one of these directories, we will add it to "List_file". 105 * 106 * List_zap All the entries which don't exist. When something appears 107 * under one of these names, the entry will be moved to either 108 * "List_file" or "List_dir", as appropriate. 109 */ 110 111 struct entry_descrip { 112 char *name; /* pathname to the entry */ 113 int fd; /* opened fd, or <= 0 if not opened */ 114 long size; /* size of entry last time checked */ 115 long mtime; /* modification time last time checked */ 116 }; 117 118 struct entry_list { 119 struct entry_descrip **list; 120 int num_entries; /* num entries stored in the list */ 121 int max_entries; /* list allocated to hold this many entries */ 122 int chunk; /* chunk for growin the list */ 123 }; 124 125 #define ENTRY_LIST_CHUNK 64 126 #define last_entry(L) ((L)->num_entries - 1) 127 128 /* 129 * The lists of entries being watched. 130 */ 131 EXTERN struct entry_list *List_file; /* regular files */ 132 EXTERN struct entry_list *List_dir; /* directories */ 133 EXTERN struct entry_list *List_zap; /* nonexistent entries */ 134 135 136 /* 137 * List sorting status. 138 * This flag indicates that "List_file" is sorted, and the right entries 139 * are open. Anything which possibly effects this state (e.g. an entry 140 * is added to "List_file", the mtime of a file is changed, etc.) must set 141 * this flag FALSE. We will periodically check this flag and call the 142 * "fixup_open_files()" procedure to resort and organize the list. 143 */ 144 EXTERN int Sorted; 145 146 147 /* 148 * Entry status control flag. 149 * The procedures which manipulate entries will reset the status information 150 * if this flag is TRUE. When initializing the lists we want this FALSE. 151 * For example, consider the file size. When initializing we want to use 152 * the current file size, otherwise we would dump the file from the beginning. 153 * However, later when we notice things are created we want to reset the 154 * size to zero so that we do dump from the beginning. 155 */ 156 EXTERN int Reset_status; 157 158 159 EXTERN int Debug; 160 EXTERN char *Progname; 161 162 163 /* 164 * Diagnostic messages produced by the "message()" procedure. 165 * The first "%s" is the entry name. The second "%s" is the errno descrip. 166 */ 167 #ifdef INTERN 168 char *mssg_list[] = { 169 NULL, /*MSSG_NONE */ 170 "\n*** %s ***\n", /*MSSG_BANNER */ 171 "\n*** '%s' has been created ***\n", /*MSSG_CREATED*/ 172 "\n*** '%s' has been deleted ***\n", /*MSSG_ZAPPED */ 173 "\n*** '%s' has been truncated - rewinding ***\n", /*MSSG_TRUNC */ 174 "\n*** error - '%s' not a file or dir - removed ***\n", /*MSSG_NOTAFIL*/ 175 "\n*** error - couldn't stat '%s' (%s) - removed ***\n",/*MSSG_STAT */ 176 "\n*** error - couldn't open '%s' (%s) - removed ***\n",/*MSSG_OPEN */ 177 "\n*** error - couldn't seek '%s' (%s) - removed ***\n",/*MSSG_SEEK */ 178 "\n*** error - couldn't read '%s' (%s) - removed ***\n",/*MSSG_READ */ 179 "\n*** error - unknown error on file '%s' ***\n", /*MSSG_UNKNOWN*/ 180 }; 181 #else 182 extern char *mssg_list[]; 183 #endif 184 185 186 /* 187 * Entry management procedures. 188 */ 189 struct entry_list *new_entry_list(int chunk); 190 struct entry_descrip *new_entry(struct entry_list *listp, const char *name); 191 void rmv_entry(struct entry_list *listp, int entryno); 192 void move_entry(struct entry_list *dst_listp, struct entry_list *src_listp, 193 int src_entryno); 194 int stat_entry(struct entry_list *listp, int entryno, struct stat *sbuf); 195 int open_entry(struct entry_list *listp, int entryno); 196 197 /* 198 * Miscellaneous procedures. 199 */ 200 int scan_directory(const char *dirname); 201 int ecmp(const void *p1, const void *p2); 202 void fixup_open_files(void); 203 void message(int sel, const struct entry_descrip *e); 204 void show_status(void); 205 char *quit_ch(void); 206 VOID *safe_malloc(size_t n); 207 VOID *safe_realloc(VOID *p, size_t n); 208 char *safe_strdup(const char *p); 209 char *basename(char *p); 210 #ifndef HAVE_DIFFTIME 211 double difftime(time_t t1, time_t t0) 212 #endif 213 #ifndef HAVE_STRERROR 214 char *strerror(int err); 215 #endif 216 217