2 * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
3 * This file is part of Jam - see jam.c for Copyright information.
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, version 3 of the License ONLY.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 * timestamp.c - get the timestamp of a file or archive member
24 #include "timestamp.h"
29 * BINDING - all known files
32 #define BIND_SCANNED 0x01 /* if directory or arch, has been scanned */
35 BIND_INIT
, /* never seen */
36 BIND_NOENTRY
, /* timestamp requested but file never found */
37 BIND_SPOTTED
, /* file found but not timed yet */
38 BIND_MISSING
, /* file found but can't get timestamp */
39 BIND_FOUND
/* file found and time stamped */
43 typedef struct _binding BINDING
;
46 short flags
; // BIND_SCANNED
47 short progress
; // enum
48 time_t time
; /* update time - 0 if not exist */
52 static struct hash
*bindhash
= 0;
53 static void time_enter (void *, const char *, int, time_t);
56 static const char *time_progress
[] = {
66 * timestamp() - return timestamp on a file, if present
68 void timestamp (char *target
, time_t *time
) {
70 BINDING binding
, *b
= &binding
;
71 static char buf
[MAXJPATH
];
72 #ifdef DOWNSHIFT_PATHS
73 static char path
[MAXJPATH
];
75 do { *p
++ = tolower(*target
); } while (*target
++) ;
78 if (!bindhash
) bindhash
= hashinit(sizeof(BINDING
), "bindings");
79 /* quick path: is it there? */
81 b
->time
= b
->flags
= 0;
82 b
->progress
= BIND_INIT
;
83 if (hashenter(bindhash
, (HASHDATA
**)&b
)) b
->name
= newstr(target
); /* never freed */
84 if (b
->progress
!= BIND_INIT
) goto afterscanning
;
85 b
->progress
= BIND_NOENTRY
;
86 /* not found: have to scan for it */
87 path_parse(target
, &f1
);
88 /* scan directory if not already done so */
90 BINDING binding
, *b
= &binding
;
97 b
->time
= b
->flags
= 0;
98 b
->progress
= BIND_INIT
;
99 if (hashenter(bindhash
, (HASHDATA
**)&b
)) b
->name
= newstr(buf
); /* never freed */
100 if (!(b
->flags
&BIND_SCANNED
)) {
101 file_dirscan(buf
, time_enter
, bindhash
);
102 b
->flags
|= BIND_SCANNED
;
105 /* scan archive if not already done so */
106 if (f1
.f_member
.len
) {
107 BINDING binding
, *b
= &binding
;
111 path_build(buf
, &f2
);
113 b
->time
= b
->flags
= 0;
114 b
->progress
= BIND_INIT
;
115 if (hashenter(bindhash
, (HASHDATA
**)&b
)) b
->name
= newstr(buf
); /* never freed */
116 if (!(b
->flags
&BIND_SCANNED
)) {
117 file_archscan(buf
, time_enter
, bindhash
);
118 b
->flags
|= BIND_SCANNED
;
122 if (b
->progress
== BIND_SPOTTED
) {
123 if (file_time(b
->name
, &b
->time
) < 0) b
->progress
= BIND_MISSING
;
124 else b
->progress
= BIND_FOUND
;
126 *time
= b
->progress
== BIND_FOUND
? b
->time
: 0;
130 static void time_enter (void *closure
, const char *target
, int found
, time_t time
) {
131 BINDING binding
, *b
= &binding
;
132 struct hash
*bindhash
= (struct hash
*)closure
;
133 #ifdef DOWNSHIFT_PATHS
134 static char path
[MAXJPATH
];
136 do { *p
++ = tolower(*target
); } while (*target
++) ;
141 if (hashenter(bindhash
, (HASHDATA
**)&b
)) b
->name
= newstr(target
); /* never freed */
143 b
->progress
= found
? BIND_FOUND
: BIND_SPOTTED
;
144 if (DEBUG_BINDSCAN
) printf("time ( %s ) : %s\n", target
, time_progress
[b
->progress
]);
149 * donestamps() - free timestamp tables
151 void donestamps (void) {