/* confdefs.h. */ #define PACKAGE_NAME "GNU tar" #define PACKAGE_TARNAME "tar" #define PACKAGE_VERSION "1.15.1" #define PACKAGE_STRING "GNU tar 1.15.1" #define PACKAGE_BUGREPORT "bug-tar@gnu.org" #define PACKAGE "tar" #define VERSION "1.15.1" #define _GNU_SOURCE 1 #define STDC_HEADERS 1 #define HAVE_SYS_TYPES_H 1 #define HAVE_SYS_STAT_H 1 #define HAVE_STDLIB_H 1 #define HAVE_STRING_H 1 #define HAVE_MEMORY_H 1 #define HAVE_STRINGS_H 1 #define HAVE_INTTYPES_H 1 #define HAVE_STDINT_H 1 #define HAVE_UNISTD_H 1 #define __EXTENSIONS__ 1 #define HAVE_FCNTL_H 1 #define HAVE_LINUX_FD_H 1 #define HAVE_MEMORY_H 1 #define HAVE_SGTTY_H 1 #define HAVE_STRING_H 1 #define HAVE_SYS_PARAM_H 1 #define HAVE_SYS_MTIO_H 1 #define HAVE_SYS_TIME_H 1 #define HAVE_UNISTD_H 1 #define HAVE_LOCALE_H 1 #define HAVE_SYS_WAIT_H 1 #define HAVE__BOOL 1 #define HAVE_STDBOOL_H 1 #define HAVE_DIRENT_H 1 #define STDC_HEADERS 1 #define HAVE_STRUCT_STAT_ST_BLKSIZE 1 #define HAVE_ST_BLKSIZE 1 #define HAVE_STRUCT_STAT_ST_BLOCKS 1 #define HAVE_ST_BLOCKS 1 #define RETSIGTYPE void #define major_t int #define minor_t int #define HAVE_INTTYPES_H_WITH_UINTMAX 1 #define HAVE_STDINT_H_WITH_UINTMAX 1 #define HAVE_LONG_LONG 1 #define HAVE_INTMAX_T 1 #define HAVE_INTTYPES_H_WITH_UINTMAX 1 #define HAVE_STDINT_H_WITH_UINTMAX 1 #define HAVE_UNSIGNED_LONG_LONG 1 #define HAVE_UINTMAX_T 1 #define HAVE_ALLOCA_H 1 #define HAVE_ALLOCA 1 #define HAVE_STDLIB_H 1 #define MALLOC_0_IS_NONNULL 1 #define HAVE_LONG_DOUBLE 1 #define HAVE_DECL_CLEARERR_UNLOCKED 1 #define HAVE_DECL_FEOF_UNLOCKED 1 #define HAVE_DECL_FERROR_UNLOCKED 1 #define HAVE_DECL_FFLUSH_UNLOCKED 1 #define HAVE_DECL_FGETS_UNLOCKED 1 #define HAVE_DECL_FPUTC_UNLOCKED 1 #define HAVE_DECL_FPUTS_UNLOCKED 1 #define HAVE_DECL_FREAD_UNLOCKED 1 #define HAVE_DECL_FWRITE_UNLOCKED 1 #define HAVE_DECL_GETC_UNLOCKED 1 #define HAVE_DECL_GETCHAR_UNLOCKED 1 #define HAVE_DECL_PUTC_UNLOCKED 1 #define HAVE_DECL_PUTCHAR_UNLOCKED 1 #define USE_UNLOCKED_IO 1 #define __GETOPT_PREFIX rpl_ #define HAVE_FLOCKFILE 1 #define HAVE_FUNLOCKFILE 1 #define HAVE_ISASCII 1 #define HAVE_GETTIMEOFDAY 1 #define HAVE_SETLOCALE 1 #define HAVE_ISWPRINT 1 #define HAVE_MBSINIT 1 #define HAVE_FEATURES_H 1 #define HAVE_UNISTD_H 1 #define HAVE_FCNTL_H 1 #define HAVE_SYS_PARAM_H 1 #define HAVE_SYS_TIME_H 1 #define HAVE_STDDEF_H 1 #define HAVE_STDLIB_H 1 #define HAVE_STRING_H 1 #define HAVE_WCHAR_H 1 #define HAVE_WCTYPE_H 1 #define HAVE_UTIME_H 1 #define D_INO_IN_DIRENT 1 #define FILE_SYSTEM_ACCEPTS_DRIVE_LETTER_PREFIX 0 #define FILE_SYSTEM_BACKSLASH_IS_FILE_NAME_SEPARATOR 0 #define HAVE_LONG_FILE_NAMES 1 #define HAVE_UNISTD_H 1 #define HAVE_CHOWN 1 #define HAVE_DECL_STRERROR_R 1 #define HAVE_STRERROR_R 1 #define STRERROR_R_CHAR_P 1 #define HAVE_MBSTATE_T 1 #define HAVE_DECL_GETCWD 1 #define TIME_WITH_SYS_TIME 1 #define HAVE_STRUCT_TIMESPEC 1 #define ST_MTIM_NSEC tv_nsec #define HAVE_DECL_NANOSLEEP 1 #define HAVE_CLOCK_GETTIME 1 #define HAVE_CLOCK_SETTIME 1 #define HAVE_TM_GMTOFF 1 #define HAVE_UNSIGNED_LONG_LONG 1 #define HAVE_UINTMAX_T 1 #define HAVE_LANGINFO_CODESET 1 #define HAVE_STDLIB_H 1 #define HAVE_SYS_TIME_H 1 #define HAVE_UNISTD_H 1 #define HAVE_ALARM 1 #define HAVE_UTIME_NULL 1 #define HAVE_STRUCT_UTIMBUF 1 #define HAVE_DECL_STRTOIMAX 1 #define HAVE_DECL_STRTOUMAX 1 #define HAVE_ALLOCA 1 #define HAVE_ALLOCA_H 1 #define HAVE_DECL_PROGRAM_INVOCATION_NAME 1 #define HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME 1 #define HAVE_PATHCONF 1 #define CHOWN_FAILS_TO_HONOR_ID_OF_NEGATIVE_ONE 1 #define HAVE_STRUCT_STAT_ST_BLOCKS 1 #define HAVE_ST_BLOCKS 1 #define HAVE_FTRUNCATE 1 /* end confdefs.h. */ #include #include #include #include #include #include #include #if HAVE_FCNTL_H # include #endif #ifndef AT_FDCWD # define AT_FDCWD 0 #endif #ifdef ENAMETOOLONG # define is_ENAMETOOLONG(x) ((x) == ENAMETOOLONG) #else # define is_ENAMETOOLONG(x) 0 #endif /* Don't get link errors because mkdir is redefined to rpl_mkdir. */ #undef mkdir #ifndef S_IRWXU # define S_IRWXU 0700 #endif /* The length of this name must be 8. */ #define DIR_NAME "confdir3" #define DIR_NAME_LEN 8 #define DIR_NAME_SIZE (DIR_NAME_LEN + 1) /* The length of "../". */ #define DOTDOTSLASH_LEN 3 /* Leftover bytes in the buffer, to work around library or OS bugs. */ #define BUF_SLOP 20 int main (void) { #ifndef PATH_MAX /* The Hurd doesn't define this, so getcwd can't exhibit the bug -- at least not on a local file system. And if we were to start worrying about remote file systems, we'd have to enable the wrapper function all of the time, just to be safe. That's not worth the cost. */ exit (0); #elif ((INT_MAX / (DIR_NAME_SIZE / DOTDOTSLASH_LEN + 1) - DIR_NAME_SIZE - BUF_SLOP) <= PATH_MAX) /* FIXME: Assuming there's a system for which this is true, this should be done in a compile test. */ exit (0); #else char buf[PATH_MAX * (DIR_NAME_SIZE / DOTDOTSLASH_LEN + 1) + DIR_NAME_SIZE + BUF_SLOP]; char *cwd = getcwd (buf, PATH_MAX); size_t initial_cwd_len; size_t cwd_len; int fail = 0; size_t n_chdirs = 0; if (cwd == NULL) exit (1); cwd_len = initial_cwd_len = strlen (cwd); while (1) { size_t dotdot_max = PATH_MAX * (DIR_NAME_SIZE / DOTDOTSLASH_LEN); char *c = NULL; cwd_len += DIR_NAME_SIZE; /* If mkdir or chdir fails, be pessimistic and consider that as a failure, too. */ if (mkdir (DIR_NAME, S_IRWXU) < 0 || chdir (DIR_NAME) < 0) { printf("Failed to mkdir or chdir, %i!", cwd_len); fail = 2; break; } if (PATH_MAX <= cwd_len && cwd_len < PATH_MAX + DIR_NAME_SIZE) { c = getcwd (buf, PATH_MAX); if (!c && errno == ENOENT) { fail = 1; break; } if (c || ! (errno == ERANGE || is_ENAMETOOLONG (errno))) { fail = 2; break; } } if (dotdot_max <= cwd_len - initial_cwd_len) { struct stat st; if (dotdot_max + DIR_NAME_SIZE < cwd_len - initial_cwd_len) break; c = getcwd (buf, cwd_len + 1); if (!c) { if (! (errno == ERANGE || errno == ENOENT || is_ENAMETOOLONG (errno))) { fail = 2; break; } if (AT_FDCWD || errno == ERANGE || errno == ENOENT) { fail = 1; break; } } } if (c && strlen (c) != cwd_len) { fail = 2; break; } ++n_chdirs; } printf("path size = %i\n", cwd_len); /* Leaving behind such a deep directory is not polite. So clean up here, right away, even though the driving shell script would also clean up. */ { size_t i; /* Unlink first, in case the chdir failed. */ unlink (DIR_NAME); for (i = 0; i <= n_chdirs; i++) { if (chdir ("..") < 0) break; rmdir (DIR_NAME); } } exit (fail); #endif }