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