1313 |
|
|
1314 |
/* Return the mtime of the file or archive-member reference NAME. */ |
/* Return the mtime of the file or archive-member reference NAME. */ |
1315 |
|
|
1316 |
|
/* First, we check with stat(). If the file does not exist, then we return |
1317 |
|
NONEXISTENT_MTIME. If it does, and the symlink check flag is set, then |
1318 |
|
examine each indirection of the symlink and find the newest mtime. |
1319 |
|
This causes one duplicate stat() when -L is being used, but the code is |
1320 |
|
much cleaner. */ |
1321 |
|
|
1322 |
static FILE_TIMESTAMP |
static FILE_TIMESTAMP |
1323 |
name_mtime (char *name) |
name_mtime (char *name) |
1324 |
{ |
{ |
1325 |
|
FILE_TIMESTAMP mtime; |
1326 |
struct stat st; |
struct stat st; |
1327 |
int e; |
int e; |
1328 |
|
|
1333 |
perror_with_name ("stat:", name); |
perror_with_name ("stat:", name); |
1334 |
return NONEXISTENT_MTIME; |
return NONEXISTENT_MTIME; |
1335 |
} |
} |
1336 |
|
mtime = FILE_TIMESTAMP_STAT_MODTIME (name, st); |
1337 |
|
|
1338 |
|
#ifdef MAKE_SYMLINKS |
1339 |
|
#ifndef S_ISLNK |
1340 |
|
# define S_ISLNK(_m) (((_m)&S_IFMT)==S_IFLNK) |
1341 |
|
#endif |
1342 |
|
if (check_symlink_flag) |
1343 |
|
{ |
1344 |
|
PATH_VAR (lpath); |
1345 |
|
|
1346 |
|
/* Check each symbolic link segment (if any). Find the latest mtime |
1347 |
|
amongst all of them (and the target file of course). |
1348 |
|
Note that we have already successfully dereferenced all the links |
1349 |
|
above. So, if we run into any error trying to lstat(), or |
1350 |
|
readlink(), or whatever, something bizarre-o happened. Just give up |
1351 |
|
and use whatever mtime we've already computed at that point. */ |
1352 |
|
strcpy (lpath, name); |
1353 |
|
while (1) |
1354 |
|
{ |
1355 |
|
FILE_TIMESTAMP ltime; |
1356 |
|
PATH_VAR (lbuf); |
1357 |
|
long llen; |
1358 |
|
char *p; |
1359 |
|
|
1360 |
|
EINTRLOOP (e, lstat (lpath, &st)); |
1361 |
|
if (e) |
1362 |
|
{ |
1363 |
|
/* Eh? Just take what we have. */ |
1364 |
|
perror_with_name ("lstat: ", lpath); |
1365 |
|
break; |
1366 |
|
} |
1367 |
|
|
1368 |
|
/* If this is not a symlink, we're done (we started with the real |
1369 |
|
file's mtime so we don't need to test it again). */ |
1370 |
|
if (!S_ISLNK (st.st_mode)) |
1371 |
|
break; |
1372 |
|
|
1373 |
|
/* If this mtime is newer than what we had, keep the new one. */ |
1374 |
|
ltime = FILE_TIMESTAMP_STAT_MODTIME (lpath, st); |
1375 |
|
if (ltime > mtime) |
1376 |
|
mtime = ltime; |
1377 |
|
|
1378 |
|
/* Set up to check the file pointed to by this link. */ |
1379 |
|
EINTRLOOP (llen, readlink (lpath, lbuf, GET_PATH_MAX)); |
1380 |
|
if (llen < 0) |
1381 |
|
{ |
1382 |
|
/* Eh? Just take what we have. */ |
1383 |
|
perror_with_name ("readlink: ", lpath); |
1384 |
|
break; |
1385 |
|
} |
1386 |
|
lbuf[llen] = '\0'; |
1387 |
|
|
1388 |
|
/* If the target is fully-qualified or the source is just a |
1389 |
|
filename, then the new path is the target. Otherwise it's the |
1390 |
|
source directory plus the target. */ |
1391 |
|
if (lbuf[0] == '/' || (p = strrchr (lpath, '/')) == NULL) |
1392 |
|
strcpy (lpath, lbuf); |
1393 |
|
else if ((p - lpath) + llen + 2 > GET_PATH_MAX) |
1394 |
|
/* Eh? Path too long! Again, just go with what we have. */ |
1395 |
|
break; |
1396 |
|
else |
1397 |
|
/* Create the next step in the symlink chain. */ |
1398 |
|
strcpy (p+1, lbuf); |
1399 |
|
} |
1400 |
|
} |
1401 |
|
#endif |
1402 |
|
|
1403 |
return FILE_TIMESTAMP_STAT_MODTIME (name, st); |
return mtime; |
1404 |
} |
} |
1405 |
|
|
1406 |
|
|