242
242
243
243
#if defined(__GNUC__ )
244
244
#define _GNU_SOURCE
245
- #define unused __attribute__((__unused__))
246
245
#elif defined(_MSC_VER )
247
246
#pragma warning(disable: 4706) // C4706: assignment within conditional expression
248
- #define unused __pragma(warning(suppress:4100)) /* This unfortunately disables the warning for the whole line and the next one */
249
- #else
250
- #define unused
251
247
#endif
252
248
253
249
#ifndef DEBUG
254
250
#define DEBUG 0
255
251
#endif
256
252
257
- #if DEBUG
258
- #define unused_release
259
- #else
260
- #define unused_release unused
261
- #endif
262
-
263
253
#include <time.h>
264
254
#include <errno.h>
265
255
#include <fcntl.h>
272
262
#include <string.h>
273
263
#include <inttypes.h>
274
264
#include <locale.h>
265
+ #include <dirent.h> /* Provided by CMake on Windows */
275
266
#include <sys/stat.h>
276
267
#include <sys/types.h>
277
268
#include "cp1252/cp1252.c"
283
274
#if defined(_WIN32 )
284
275
#include <io.h>
285
276
#include <direct.h>
286
- #include "win32/dirent.c"
287
277
#include <getopt.h> /* Provided by CMake */
288
278
#else
289
- #include <dirent.h>
290
279
#include <limits.h>
291
280
#include <unistd.h>
292
281
#endif
337
326
#define exiso_target "Windows"
338
327
339
328
#if defined(_MSC_VER )
340
- #define S_ISDIR (x ) ((x) & _S_IFDIR)
341
- #define S_ISREG (x ) ((x) & _S_IFREG)
342
-
343
329
typedef SSIZE_T ssize_t ;
344
330
#define strcasecmp _stricmp
345
331
#define strncasecmp _strnicmp
353
339
#define lseek _lseeki64
354
340
#define mkdir (a , b ) _mkdir(a)
355
341
#define stat _stat64
356
- #define lstat _stat64
357
342
#define realpath (a , b ) _fullpath(b, a, _MAX_PATH)
358
343
359
344
#define bswap_16 (x ) _byteswap_ushort(x)
@@ -425,6 +410,21 @@ typedef int64_t file_time_t;
425
410
#define max (a , b ) ( (a) > (b) ? (a) : (b) )
426
411
#endif
427
412
413
+ /* These definitions need to be after all the includes */
414
+ #if defined(__GNUC__ )
415
+ #define unused __attribute__((__unused__))
416
+ #elif defined(_MSC_VER )
417
+ #define unused __pragma(warning(suppress:4100)) /* This unfortunately disables the warning for the whole line and the next one */
418
+ #else
419
+ #define unused
420
+ #endif
421
+
422
+ #if DEBUG
423
+ #define unused_release
424
+ #else
425
+ #define unused_release unused
426
+ #endif
427
+
428
428
#define exiso_version "2.7.1 (01.11.14)"
429
429
#define VERSION_LENGTH 16
430
430
@@ -619,6 +619,9 @@ int calculate_directory_offsets( dir_node_avl *in_avl, uint32_t *io_context, int
619
619
int write_dir_start_and_file_positions ( dir_node_avl * in_avl , wdsafp_context * io_context , int in_depth );
620
620
int write_volume_descriptors ( int in_xiso , uint32_t in_total_sectors );
621
621
622
+ static int is_lnk_lstat (struct dirent * p , bool * lnk );
623
+ static int is_lnk (struct dirent * p , bool * lnk );
624
+
622
625
#if DEBUG
623
626
void write_sector ( int in_xiso , xoff_t in_start , const char * in_name , const char * in_extension );
624
627
#endif
@@ -2014,14 +2017,49 @@ int calculate_directory_size( dir_node_avl *in_avl, uint32_t *out_size, int in_d
2014
2017
return 0 ;
2015
2018
}
2016
2019
2020
+ static int is_lnk_lstat (struct dirent * p , bool * lnk ) {
2021
+ if (p == NULL || lnk == NULL ) {
2022
+ errno = EFAULT ;
2023
+ return -1 ;
2024
+ }
2025
+ #if !defined(_WIN32 )
2026
+ struct stat sb = { 0 };
2027
+ if (lstat (p -> d_name , & sb ) == -1 ) {
2028
+ return -1 ;
2029
+ }
2030
+ * lnk = S_ISLNK (sb .st_mode );
2031
+ #else
2032
+ * lnk = false;
2033
+ #endif // _WIN32
2034
+ return 0 ;
2035
+ }
2036
+
2037
+ static int is_lnk (struct dirent * p , bool * lnk ) {
2038
+ if (p == NULL || lnk == NULL ) {
2039
+ errno = EFAULT ;
2040
+ return -1 ;
2041
+ }
2042
+ #if defined(_DIRENT_HAVE_D_TYPE )
2043
+ if (p -> d_type == DT_UNKNOWN ) {
2044
+ return is_lnk_lstat (p , lnk );
2045
+ }
2046
+ else {
2047
+ * lnk = (p -> d_type == DT_LNK );
2048
+ return 0 ;
2049
+ }
2050
+ #else
2051
+ return is_lnk_lstat (p , lnk );
2052
+ #endif // _DIRENT_HAVE_D_TYPE
2053
+ }
2054
+
2017
2055
2018
2056
int generate_avl_tree_local ( dir_node_avl * * out_root , int * io_n ) {
2019
2057
struct dirent * p = NULL ;
2020
2058
struct stat sb = { 0 };
2021
2059
dir_node_avl * avl = NULL ;
2022
2060
DIR * dir = NULL ;
2023
2061
int err = 0 , i = 0 , j = 0 ;
2024
- bool empty_dir = true;
2062
+ bool empty_dir = true, lnk ;
2025
2063
2026
2064
if ( ( dir = opendir ( "." ) ) == NULL ) mem_err ();
2027
2065
@@ -2034,16 +2072,19 @@ int generate_avl_tree_local( dir_node_avl **out_root, int *io_n ) {
2034
2072
for ( j = i ; j < * io_n ; ++ j ) exiso_log ( "\b" );
2035
2073
* io_n = i ;
2036
2074
flush ();
2075
+
2076
+ if (is_lnk (p , & lnk ) == -1 ) read_err ();
2077
+ else if (lnk ) continue ;
2037
2078
2038
- if ( ( avl = (dir_node_avl * ) calloc ( 1 , sizeof (dir_node_avl ) ) ) == NULL ) mem_err ();
2079
+ if (! err && ( avl = (dir_node_avl * ) calloc ( 1 , sizeof (dir_node_avl ) ) ) == NULL ) mem_err ();
2039
2080
if (!err && (avl -> filename = strdup (p -> d_name )) == NULL ) mem_err ();
2040
2081
if (!err ) {
2041
2082
if (s_cp1252 ) {
2042
2083
avl -> filename_cp1252 = avl -> filename ;
2043
2084
avl -> filename = NULL ;
2044
2085
} else if ((avl -> filename_cp1252 = getCP1252String (p -> d_name )) == NULL ) mem_err ();
2045
2086
}
2046
- if ( ! err && lstat ( p -> d_name , & sb ) == -1 ) read_err ();
2087
+ if ( ! err && stat ( p -> d_name , & sb ) == -1 ) read_err ();
2047
2088
if ( ! err ) {
2048
2089
if ( S_ISDIR ( sb .st_mode ) ) {
2049
2090
empty_dir = false;
0 commit comments