Subversion Repositories tendra.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 7u83 1
/*
7 7u83 2
 * Copyright (c) 2002-2006 The TenDRA Project <http://www.tendra.org/>.
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are met:
7
 *
8
 * 1. Redistributions of source code must retain the above copyright notice,
9
 *    this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright notice,
11
 *    this list of conditions and the following disclaimer in the documentation
12
 *    and/or other materials provided with the distribution.
13
 * 3. Neither the name of The TenDRA Project nor the names of its contributors
14
 *    may be used to endorse or promote products derived from this software
15
 *    without specific, prior written permission.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
18
 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
19
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
21
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22
 * EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
 *
29
 * $Id$
30
 */
31
/*
2 7u83 32
    		 Crown Copyright (c) 1997
7 7u83 33
 
2 7u83 34
    This TenDRA(r) Computer Program is subject to Copyright
35
    owned by the United Kingdom Secretary of State for Defence
36
    acting through the Defence Evaluation and Research Agency
37
    (DERA).  It is made available to Recipients with a
38
    royalty-free licence for its use, reproduction, transfer
39
    to other parties and amendment for any purpose not excluding
40
    product development provided that any such use et cetera
41
    shall be deemed to be acceptance of the following conditions:-
7 7u83 42
 
2 7u83 43
        (1) Its Recipients shall ensure that this Notice is
44
        reproduced upon any copies or amended versions of it;
7 7u83 45
 
2 7u83 46
        (2) Any amended version of it shall be clearly marked to
47
        show both the nature of and the organisation responsible
48
        for the relevant amendment or amendments;
7 7u83 49
 
2 7u83 50
        (3) Its onward transfer from a recipient to another
51
        party shall be deemed to be that party's acceptance of
52
        these conditions;
7 7u83 53
 
2 7u83 54
        (4) DERA gives no warranty or assurance as to its
55
        quality or suitability for any purpose and DERA accepts
56
        no liability whatsoever in relation to any use to which
57
        it may be put.
58
*/
59
 
60
 
61
#include "config.h"
62
#include "system.h"
63
#include "c_types.h"
64
#include "error.h"
65
#include "file.h"
66
#include "ustring.h"
67
#include "xalloc.h"
68
 
69
 
70
/*
71
    FILE SEEKING FLAG
72
 
73
    The flag good_fseek is true if a simple fseek on the byte count has
74
    the desired effect, and false otherwise (for example on DOS machines).
75
    Similarly binary_mode is true if there are separate text and binary
76
    file modes.  The flag good_stat is true if the st_dev and st_ino
77
    fields of struct stat are sufficient to uniquely identify a file
78
    (this may not be true for machines with small ino_t types and
79
    file systems mounted from machines with large ino_t types).
80
*/
81
 
7 7u83 82
int good_fseek = 1;
83
int good_stat = 0;
84
int text_mode = 0;
85
int binary_mode = 0;
86
int file_sep = '/';
87
int drive_sep = 0;
2 7u83 88
 
89
 
90
/*
91
    SEEK A POSITION IN A FILE
92
 
93
    This routine seeks a position n bytes from the start of the file f.
94
    It returns 0 if good_fseek is false, otherwise it returns 1 for
95
    successful seeks and -1 otherwise.
96
*/
97
 
7 7u83 98
int
99
file_seek(FILE *f, long n)
2 7u83 100
{
7 7u83 101
	if (n == 0) {
102
		/* Can always rewind a file */
103
		rewind(f);
104
		return (1);
105
	}
106
	if (good_fseek) {
107
		/* Use fseek if it works */
108
		int s = fseek(f, n, SEEK_SET);
109
		if (s == -1) {
110
			return (-1);
111
		}
112
		return (1);
113
	}
114
	return (0);
2 7u83 115
}
116
 
117
 
118
/*
119
    CONVERT A TIME TO AN UNSIGNED LONG
120
 
121
    This macro converts the time_t value A to an unsigned long.  Since
122
    time_t may be any arithmetic type, this may not be totally portable.
123
*/
124
 
7 7u83 125
#define time_value(A)		((unsigned long)(A))
2 7u83 126
 
127
 
128
/*
129
    CURRENT TIME
130
 
131
    These variables are used to hold the current time as a struct tm.
132
    The date is also used to form a string which is unique for each
133
    translation unit.
134
*/
135
 
7 7u83 136
char uniq_string[50];
137
unsigned long crt_time = 0;
138
static int have_crt_time = 0;
139
static struct tm crt_time_str;
2 7u83 140
 
141
 
142
/*
143
    FIND THE CURRENT TIME
144
 
145
    This routine assigns the current time to the variables above, returning
146
    a pointer to crt_time_str.  Note that the actual time is taken only the
147
    first time the function is called.
148
*/
149
 
7 7u83 150
static struct tm *
151
get_crt_time(void)
2 7u83 152
{
7 7u83 153
	if (!have_crt_time) {
154
		CONST char *s1, *s2;
155
		time_t t = time(NIL(time_t));
156
		if (t == (time_t) -1) {
157
			/* Use a (seemingly) random date if time fails */
158
			struct tm *st = &crt_time_str;
159
			st->tm_mday = 24;
160
			st->tm_mon = 6 /* July */ ;
161
			st->tm_year = 62;
162
			st->tm_hour = 23;
163
			st->tm_min = 30;
164
			st->tm_sec = 0;
165
			error(ERROR_INTERNAL, "Can't find current date");
166
		} else {
167
			struct tm *st = localtime(&t);
168
			crt_time_str = *st;
169
			crt_time = time_value(t);
170
		}
171
		have_crt_time = 1;
172
		s1 = find_time("%.2d%.2d%.2d");
173
		s2 = find_date("%s%.2d_%d");
174
		sprintf_v(uniq_string, "%s_%s", s1, s2);
2 7u83 175
	}
7 7u83 176
	return (&crt_time_str);
2 7u83 177
}
178
 
179
 
180
/*
181
    PRINT THE CURRENT DATE
182
 
183
    This routine returns a string giving the current date in the form
184
    given by fmt.  This is used in the __DATE__ built-in macro.
185
*/
186
 
7 7u83 187
CONST char *
188
find_date(CONST char *fmt)
2 7u83 189
{
7 7u83 190
	static char buff[20];
191
	static CONST char *month_name[12] = {
192
		"Jan", "Feb", "Mar", "Apr", "May", "Jun",
193
		"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
194
	};
195
	struct tm *st = get_crt_time();
196
	int day = st->tm_mday;
197
	CONST char *month = month_name[st->tm_mon];
198
	int year = 1900 + st->tm_year;
199
	sprintf_v(buff, fmt, month, day, year);
200
	return (buff);
2 7u83 201
}
202
 
203
 
204
/*
205
    PRINT THE CURRENT TIME
206
 
207
    This routine returns a string giving the current time in the form
208
    given by fmt.  This is used in the __TIME__ built-in macro.
209
*/
210
 
7 7u83 211
CONST char *
212
find_time(CONST char *fmt)
2 7u83 213
{
7 7u83 214
	static char buff[20];
215
	struct tm *st = get_crt_time();
216
	int hour = st->tm_hour;
217
	int min = st->tm_min;
218
	int sec = st->tm_sec;
219
	sprintf_v(buff, fmt, hour, min, sec);
220
	return (buff);
2 7u83 221
}
222
 
223
 
224
/*
225
    FIND FILE STATISTICS
226
 
227
    This routine finds the file statistics for the file with pathname nm
228
    and assigns them into fs.  It returns fs if this is successful and the
229
    null pointer otherwise.
230
*/
231
 
7 7u83 232
STAT_TYPE *
233
stat_func(char *nm, STAT_TYPE *fs)
2 7u83 234
{
235
#if FS_POSIX
7 7u83 236
	int s = stat(nm, fs);
237
	if (s != -1) {
238
		return (fs);
239
	}
2 7u83 240
#endif
7 7u83 241
	UNUSED(nm);
242
	return (NULL);
2 7u83 243
}
244
 
245
 
246
/*
247
    FIND A FILE DATE
248
 
249
    This routine converts the date from the file statistics fs to an
250
    unsigned long.
251
*/
252
 
7 7u83 253
unsigned long
254
stat_date(STAT_TYPE *fs)
2 7u83 255
{
7 7u83 256
	unsigned long date = 0;
257
	if (fs) {
258
		date = time_value(fs->st_mtime);
259
	}
260
	return (date);
2 7u83 261
}
262
 
263
 
264
/*
265
    ARE TWO FILES EQUAL?
266
 
267
    This routine checks whether the files given by the statistics fs and
268
    gs represent the same file.  Two files are the same if their device
269
    and inode numbers are equal (except on machines where good_stat is
270
    false).
271
*/
272
 
7 7u83 273
int
274
stat_equal(STAT_TYPE *fs, STAT_TYPE *gs)
2 7u83 275
{
7 7u83 276
	if (fs && gs) {
277
		if (fs->st_dev == gs->st_dev && fs->st_ino == gs->st_ino) {
278
			return (good_stat);
279
		}
2 7u83 280
	}
7 7u83 281
	return (0);
2 7u83 282
}
283
 
284
 
285
/*
286
    FIND THE CURRENT WORKING DIRECTORY
287
 
288
    This routine finds the current working directory, returning '.' if
289
    this cannot be found.
290
*/
291
 
7 7u83 292
CONST char *
293
find_cwd(void)
2 7u83 294
{
7 7u83 295
	static CONST char *crt_directory = NULL;
296
	if (crt_directory == NULL) {
2 7u83 297
#if FS_POSIX
7 7u83 298
		char buff[1024];
299
		char *nm = getcwd(buff, 1024);
300
		if (nm) {
301
			/* Copy result */
302
			string dir = xustrcpy(ustrlit(nm));
303
			dir = make_pathname(dir);
304
			crt_directory = strlit(dir);
305
		} else {
306
			crt_directory = ".";
307
		}
2 7u83 308
#else
7 7u83 309
		crt_directory = ".";
2 7u83 310
#endif
7 7u83 311
	}
312
	return (crt_directory);
2 7u83 313
}
314
 
315
 
316
/*
317
    FIND THE CURRENT MACHINE
318
 
319
    This routine finds the name of the machine on which the program is
320
    running, returning the empty string if this cannot be found.
321
*/
322
 
7 7u83 323
CONST char *
324
find_machine(void)
2 7u83 325
{
7 7u83 326
	static CONST char *machine_name = NULL;
327
	if (machine_name == NULL) {
2 7u83 328
#if FS_UTSNAME
7 7u83 329
		struct utsname un;
330
		if (uname(&un) != -1) {
331
			string s = ustrlit(un.nodename);
332
			s = xustrcpy(s);
333
			machine_name = strlit(s);
334
			return (machine_name);
335
		}
336
#endif
337
		machine_name = "";
2 7u83 338
	}
7 7u83 339
	return (machine_name);
2 7u83 340
}