debian-cd-clone/mkhybrid.diff

930 lines
24 KiB
Diff

--- mkhybrid-1.12a4.7/mkisofs.c Mon Aug 24 20:12:55 1998
+++ mkhybrid-1.12a4.7.new/mkisofs.c Thu Jan 14 11:53:57 1999
@@ -91,6 +91,7 @@
int verbose = 1;
int all_files = 0;
int follow_links = 0;
+int follow_links_sensible = 0;
int rationalize = 0;
int generate_tables = 0;
int print_size = 0;
@@ -106,6 +107,7 @@
char * system_id = SYSTEM_ID_DEFAULT;
char * boot_catalog = BOOT_CATALOG_DEFAULT;
char * boot_image = BOOT_IMAGE_DEFAULT;
+char follow_links_base[256];
int omit_period = 0; /* Violates iso9660, but these are a pain */
int transparent_compression = 0; /* So far only works with linux */
@@ -237,6 +239,8 @@
'D', NULL, "Disable deep directory relocation", ONE_DASH },
{ {"follow-links", no_argument, NULL, 'f'},
'f', NULL, "Follow symbolic links", ONE_DASH },
+ { {"follow-outside-links", required_argument, NULL, 'F'},
+ 'F', NULL, "Follow symbolic links which point outside the CD base directory", ONE_DASH },
#ifdef APPLE_HYB
{ {"apple", no_argument, NULL, 'g'},
'g', NULL, "Add Apple ISO9660 extensions", ONE_DASH },
@@ -682,6 +686,8 @@
char *log_file = 0; /* stderr log file re-direct */
#endif /* APPLE_HYB */
+ char old_dir[256];
+
if (argc < 2)
usage();
@@ -773,181 +779,189 @@
}
break;
case 'A':
- appid = optarg;
- if(strlen(appid) > 128) {
- fprintf(stderr,"Application-id string too long\n");
- exit(1);
- };
- break;
+ appid = optarg;
+ if(strlen(appid) > 128)
+ {
+ fprintf(stderr,"Application-id string too long\n");
+ exit(1);
+ }
+ break;
case 'd':
- omit_period++;
- break;
+ omit_period++;
+ break;
case 'D':
- RR_relocation_depth = 32767;
- break;
+ RR_relocation_depth = 32767;
+ break;
case 'f':
- follow_links++;
- break;
+ follow_links++;
+ break;
+ case 'F':
+ follow_links_sensible++;
+ getcwd (old_dir, 256);
+ chdir (optarg);
+ getcwd (follow_links_base, 256);
+ chdir (old_dir);
+ break;
case 'l':
- full_iso9660_filenames++;
- break;
+ full_iso9660_filenames++;
+ break;
case 'L':
- allow_leading_dots++;
- break;
+ allow_leading_dots++;
+ break;
case 'M':
- merge_image = optarg;
- break;
+ merge_image = optarg;
+ break;
case 'N':
- omit_version_number++;
- break;
+ omit_version_number++;
+ break;
case 'o':
- outfile = optarg;
- break;
+ outfile = optarg;
+ break;
case 'p':
- preparer = optarg;
- if(strlen(preparer) > 128) {
- fprintf(stderr,"Preparer string too long\n");
- exit(1);
- };
- break;
+ preparer = optarg;
+ if(strlen(preparer) > 128) {
+ fprintf(stderr,"Preparer string too long\n");
+ exit(1);
+ };
+ break;
case OPTION_PRINT_SIZE:
- print_size++;
- break;
+ print_size++;
+ break;
case 'P':
- publisher = optarg;
- if(strlen(publisher) > 128) {
- fprintf(stderr,"Publisher string too long\n");
- exit(1);
- };
- break;
+ publisher = optarg;
+ if(strlen(publisher) > 128) {
+ fprintf(stderr,"Publisher string too long\n");
+ exit(1);
+ };
+ break;
case OPTION_QUIET:
- verbose = 0;
- break;
+ verbose = 0;
+ break;
case 'R':
- use_RockRidge++;
- break;
+ use_RockRidge++;
+ break;
case 'r':
- rationalize++;
- use_RockRidge++;
- break;
+ rationalize++;
+ use_RockRidge++;
+ break;
case OPTION_SPLIT_OUTPUT:
- split_output++;
- break;
+ split_output++;
+ break;
#ifdef APPLE_HYB
case OPTION_TRANS_TBL:
- trans_tbl = optarg;
- /* fall through */
+ trans_tbl = optarg;
+ /* fall through */
#endif /* APPLE_HYB */
case 'T':
- generate_tables++;
- break;
+ generate_tables++;
+ break;
case 'V':
- volume_id = optarg;
- break;
+ volume_id = optarg;
+ break;
case 'v':
- verbose++;
- break;
+ verbose++;
+ break;
case 'z':
#ifdef VMS
- fprintf(stderr,"Transparent compression not supported with VMS\n");
- exit(1);
+ fprintf(stderr,"Transparent compression not supported with VMS\n");
+ exit(1);
#else
- transparent_compression++;
+ transparent_compression++;
#endif
- break;
+ break;
case 'x':
case 'm':
- /*
- * Somehow two options to do basically the same thing got added somewhere along
- * the way. The 'match' code supports limited globbing, so this is the one
- * that got selected. Unfortunately the 'x' switch is probably more intuitive.
+ /*
+ * Somehow two options to do basically the same thing got added somewhere along
+ * the way. The 'match' code supports limited globbing, so this is the one
+ * that got selected. Unfortunately the 'x' switch is probably more intuitive.
*/
- add_match(optarg);
- break;
+ add_match(optarg);
+ break;
case OPTION_I_HIDE:
- i_add_match(optarg);
- break;
+ i_add_match(optarg);
+ break;
case OPTION_J_HIDE:
- j_add_match(optarg);
- break;
+ j_add_match(optarg);
+ break;
case OPTION_HELP:
- usage ();
- exit (0);
- break;
+ usage ();
+ exit (0);
+ break;
case OPTION_NOSPLIT_SL_COMPONENT:
- split_SL_component = 0;
- break;
+ split_SL_component = 0;
+ break;
case OPTION_NOSPLIT_SL_FIELD:
- split_SL_field = 0;
- break;
+ split_SL_field = 0;
+ break;
#ifdef APPLE_HYB
case 'H':
- afpfile = optarg;
- hfs_last = MAP_LAST;
- break;
+ afpfile = optarg;
+ hfs_last = MAP_LAST;
+ break;
case 'h':
- apple_hyb = 1;
- break;
+ apple_hyb = 1;
+ break;
case 'g':
- apple_ext = 1;
- break;
+ apple_ext = 1;
+ break;
case OPTION_PROBE:
- probe = 1;
- break;
+ probe = 1;
+ break;
case OPTION_MACNAME:
- mac_name = 1;
- break;
+ mac_name = 1;
+ break;
case OPTION_NOMACFILES:
- nomacfiles = 1;
- break;
+ nomacfiles = 1;
+ break;
case OPTION_BOOT_HFS_FILE:
- hfs_boot_file = optarg;
- break;
+ hfs_boot_file = optarg;
+ break;
case OPTION_MAGIC_FILE:
- magic_file = optarg;
- hfs_last = MAG_LAST;
- break;
- /* Mac/Unix types to include */
+ magic_file = optarg;
+ hfs_last = MAG_LAST;
+ break;
+ /* Mac/Unix types to include */
case OPTION_CAP:
- hfs_select |= DO_CAP;
- break;
+ hfs_select |= DO_CAP;
+ break;
case OPTION_NETA:
- hfs_select |= DO_NETA;
- break;
+ hfs_select |= DO_NETA;
+ break;
case OPTION_DBL:
- hfs_select |= DO_DBL;
- break;
+ hfs_select |= DO_DBL;
+ break;
case OPTION_ESH:
case OPTION_USH:
- hfs_select |= DO_ESH;
- break;
+ hfs_select |= DO_ESH;
+ break;
case OPTION_FE:
- hfs_select |= DO_FEU;
- hfs_select |= DO_FEL;
- break;
+ hfs_select |= DO_FEU;
+ hfs_select |= DO_FEL;
+ break;
case OPTION_SGI:
case OPTION_XIN:
- hfs_select |= DO_SGI;
- break;
+ hfs_select |= DO_SGI;
+ break;
case OPTION_MBIN:
- hfs_select |= DO_MBIN;
- break;
+ hfs_select |= DO_MBIN;
+ break;
case OPTION_SGL:
- hfs_select |= DO_SGL;
- break;
+ hfs_select |= DO_SGL;
+ break;
case OPTION_CREATE_DT:
- create_dt = 0;
- break;
+ create_dt = 0;
+ break;
case OPTION_HFS_HIDE:
- hfs_add_match(optarg);
- break;
+ hfs_add_match(optarg);
+ break;
case OPTION_LOG_FILE:
- log_file = optarg;
- break;
+ log_file = optarg;
+ break;
#endif /* APPLE_HYB */
default:
- usage();
- exit(1);
+ usage();
+ exit(1);
}
parse_input_files:
diff -u mkhybrid-1.12a4.7/mkisofs.h mkhybrid-1.12a4.7.new/mkisofs.h
--- mkhybrid-1.12a4.7/mkisofs.h Mon Aug 24 19:55:07 1998
+++ mkhybrid-1.12a4.7.new/mkisofs.h Tue Jan 12 11:27:10 1999
@@ -280,6 +280,8 @@
extern int use_Joliet;
extern int rationalize;
extern int follow_links;
+extern int follow_links_sensible;
+extern char follow_links_base[];
extern int verbose;
extern int all_files;
extern int generate_tables;
--- mkhybrid-1.12a4.7/tree.c Mon Aug 24 20:06:37 1998
+++ mkhybrid-1.12a4.7.new/tree.c Thu Jan 14 12:03:29 1999
@@ -827,165 +827,181 @@
char *, path,
struct directory_entry *, de)
{
- DIR * current_dir;
- char whole_path[1024];
- struct dirent * d_entry;
- struct directory * parent;
- int dflag;
- char * old_path;
+ DIR * current_dir;
+ char whole_path[1024];
+ struct dirent * d_entry;
+ struct directory * parent;
+ int dflag;
+ char * old_path;
- current_dir = opendir(path);
- d_entry = NULL;
+ current_dir = opendir(path);
+ d_entry = NULL;
- /* Apparently NFS sometimes allows you to open the directory, but
- then refuses to allow you to read the contents. Allow for this */
+ /* Apparently NFS sometimes allows you to open the directory, but
+ then refuses to allow you to read the contents. Allow for this */
- old_path = path;
+ old_path = path;
- if(current_dir) d_entry = readdir(current_dir);
+ if(current_dir) d_entry = readdir(current_dir);
- if(!current_dir || !d_entry)
+ if(!current_dir || !d_entry)
{
- fprintf(stderr,"Unable to open directory %s\n", path);
- de->isorec.flags[0] &= ~2; /* Mark as not a directory */
- if(current_dir) closedir(current_dir);
- return 0;
+ fprintf(stderr,"Unable to open directory %s\n", path);
+ de->isorec.flags[0] &= ~2; /* Mark as not a directory */
+ if(current_dir) closedir(current_dir);
+ return 0;
}
- parent = de->filedir;
- /* Set up the struct for the current directory, and insert it into the
- tree */
+ parent = de->filedir;
+ /* Set up the struct for the current directory, and insert it into the
+ tree */
#ifdef VMS
- vms_path_fixup(path);
+ vms_path_fixup(path);
#endif
- /*
- * if entry for this sub-directory is hidden, then hide this directory
- */
- if (de->de_flags & INHIBIT_ISO9660_ENTRY)
- this_dir->dir_flags |= INHIBIT_ISO9660_ENTRY;
+ /*
+ * if entry for this sub-directory is hidden, then hide this directory
+ */
+ if (de->de_flags & INHIBIT_ISO9660_ENTRY)
+ this_dir->dir_flags |= INHIBIT_ISO9660_ENTRY;
- if (de->de_flags & INHIBIT_JOLIET_ENTRY)
- this_dir->dir_flags |= INHIBIT_JOLIET_ENTRY;
+ if (de->de_flags & INHIBIT_JOLIET_ENTRY)
+ this_dir->dir_flags |= INHIBIT_JOLIET_ENTRY;
- /*
- * Now we scan the directory itself, and look at what is inside of it.
- */
- dflag = 0;
- while(1==1){
+ /*
+ * Now we scan the directory itself, and look at what is inside of it.
+ */
+ dflag = 0;
+ while(1==1)
+ {
- /* The first time through, skip this, since we already asked for
- the first entry when we opened the directory. */
- if(dflag) d_entry = readdir(current_dir);
- dflag++;
-
- if(!d_entry) break;
-
- /* OK, got a valid entry */
-
- /* If we do not want all files, then pitch the backups. */
- if(!all_files){
- if( strchr(d_entry->d_name,'~')
- || strchr(d_entry->d_name,'#'))
- {
- if( verbose > 0 )
- {
- fprintf(stderr, "Ignoring file %s\n", d_entry->d_name);
- }
- continue;
- }
- }
+ /* The first time through, skip this, since we already asked for
+ the first entry when we opened the directory. */
+ if(dflag)
+ d_entry = readdir(current_dir);
+ dflag++;
+
+ if(!d_entry)
+ break;
+
+ /* OK, got a valid entry */
+
+ /* If we do not want all files, then pitch the backups. */
+ if(!all_files)
+ {
+ if(strchr(d_entry->d_name,'~') || strchr(d_entry->d_name,'#'))
+ {
+ if( verbose > 0 )
+ fprintf(stderr, "Ignoring file %s\n", d_entry->d_name);
+ continue;
+ }
+ }
#ifdef APPLE_HYB
- if (apple_both) {
- /* exclude certain HFS type files/directories for the time being */
- if (hfs_exclude(d_entry->d_name))
- continue;
- }
+ if (apple_both) {
+ /* exclude certain HFS type files/directories for the time being */
+ if (hfs_exclude(d_entry->d_name))
+ continue;
+ }
#endif /* APPLE_HYB */
- if(strlen(path)+strlen(d_entry->d_name) + 2 > sizeof(whole_path)){
- fprintf(stderr, "Overflow of stat buffer\n");
- exit(1);
- };
+ if(strlen(path)+strlen(d_entry->d_name) + 2 > sizeof(whole_path))
+ {
+ fprintf(stderr, "Overflow of stat buffer\n");
+ exit(1);
+ };
- /* Generate the complete ASCII path for this file */
- strcpy(whole_path, path);
+ /* Generate the complete ASCII path for this file */
+ strcpy(whole_path, path);
#ifndef VMS
- if(whole_path[strlen(whole_path)-1] != '/')
- strcat(whole_path, "/");
+ if(whole_path[strlen(whole_path)-1] != '/')
+ strcat(whole_path, "/");
#endif
- strcat(whole_path, d_entry->d_name);
+ strcat(whole_path, d_entry->d_name);
- /** Should we exclude this file ? */
- if (matches(d_entry->d_name) || matches(whole_path)) {
- if (verbose > 1) {
- fprintf(stderr, "Excluded by match: %s\n", whole_path);
- }
- continue;
- }
+ /** Should we exclude this file ? */
+ if (matches(d_entry->d_name) || matches(whole_path))
+ {
+ if (verbose > 1)
+ fprintf(stderr, "Excluded by match: %s\n", whole_path);
+ continue;
+ }
- if( generate_tables
#ifdef APPLE_HYB
- && strcmp(d_entry->d_name, trans_tbl) == 0 )
+ if(generate_tables && strcmp(d_entry->d_name, trans_tbl) == 0 )
#else
- && strcmp(d_entry->d_name, "TRANS.TBL") == 0 )
+ if(generate_tables && strcmp(d_entry->d_name, "TRANS.TBL") == 0 )
#endif /* APPLE_HYB */
- {
- /*
- * Ignore this entry. We are going to be generating new
- * versions of these files, and we need to ignore any
- * originals that we might have found.
- */
- if (verbose > 1)
- {
- fprintf(stderr, "Excluded: %s\n",whole_path);
- }
- continue;
- }
-
- /*
- * If we already have a '.' or a '..' entry, then don't
- * insert new ones.
- */
- if( strcmp(d_entry->d_name, ".") == 0
- && this_dir->dir_flags & DIR_HAS_DOT )
- {
- continue;
- }
-
- if( strcmp(d_entry->d_name, "..") == 0
- && this_dir->dir_flags & DIR_HAS_DOTDOT )
- {
- continue;
- }
+ {
+ /*
+ * Ignore this entry. We are going to be generating new
+ * versions of these files, and we need to ignore any
+ * originals that we might have found.
+ */
+ if (verbose > 1)
+ fprintf(stderr, "Excluded: %s\n",whole_path);
+ continue;
+ }
+
+ /*
+ * If we already have a '.' or a '..' entry, then don't
+ * insert new ones.
+ */
+ if(strcmp(d_entry->d_name,".") == 0 && this_dir->dir_flags & DIR_HAS_DOT)
+ continue;
+
+ if(strcmp(d_entry->d_name,"..") == 0 && this_dir->dir_flags&DIR_HAS_DOTDOT)
+ continue;
#if 0
- if (verbose > 1) fprintf(stderr, "%s\n",whole_path);
+ if (verbose > 1) fprintf(stderr, "%s\n",whole_path);
#endif
- /*
+ /*
* This actually adds the entry to the directory in question.
*/
#ifdef APPLE_HYB
- insert_file_entry(this_dir, whole_path, d_entry->d_name, 0);
+ insert_file_entry(this_dir, whole_path, d_entry->d_name, 0);
#else
- insert_file_entry(this_dir, whole_path, d_entry->d_name);
+ insert_file_entry(this_dir, whole_path, d_entry->d_name);
#endif /* APPLE_HYB */
- }
- closedir(current_dir);
+ }
+
+ closedir(current_dir);
#ifdef APPLE_HYB
- /* if we cached the HFS info stuff for this directory, then delete it */
- if (this_dir->hfs_info) {
- del_hfs_info(this_dir->hfs_info);
- this_dir->hfs_info = 0;
- }
+/* if we cached the HFS info stuff for this directory, then delete it */
+ if (this_dir->hfs_info) {
+ del_hfs_info(this_dir->hfs_info);
+ this_dir->hfs_info = 0;
+ }
#endif /* APPLE_HYB */
-
- return 1;
+ return 1;
}
+/* check_dirlevel: returns 1 if
+ * name is below the tree of follow_links_base */
+int check_dirlevel (char *name)
+{
+ char old[256] = {0,}, buf[256] = {0,}, b2[256], *c;
+
+ strcpy (b2, name);
+ c = strrchr (b2, '/');
+ if (c)
+ {
+ *c = '\0';
+ getcwd (old, 256);
+ chdir (b2);
+ getcwd (buf, 256);
+ chdir (old);
+
+ if (!strncmp (buf, follow_links_base, strlen (follow_links_base)))
+ return 1;
+ return 0;
+ }
+ else
+ return 1;
+}
/*
* Function: insert_file_entry
@@ -1008,132 +1024,170 @@
char *, short_name,
int, have_rsrc)
#else
-int
+ int
FDECL3(insert_file_entry,struct directory *, this_dir,
char *, whole_path,
char *, short_name)
#endif /* APPLE_HYB */
{
- struct stat statbuf, lstatbuf;
- struct directory_entry * s_entry, *s_entry1;
- int lstatus;
- int status;
- int deep_flag;
+ struct stat statbuf, lstatbuf;
+ struct directory_entry * s_entry, *s_entry1;
+ int lstatus;
+ int status;
+ int deep_flag;
#ifdef APPLE_HYB
- int x_hfs = 0;
- int htype;
+ int x_hfs = 0;
+ int htype;
#endif /* APPLE_HYB */
+ char link_buf[256];
+ int do_follow_links = 0;
- status = stat_filter(whole_path, &statbuf);
+ status = stat_filter(whole_path, &statbuf);
- lstatus = lstat_filter(whole_path, &lstatbuf);
+ lstatus = lstat_filter(whole_path, &lstatbuf);
- if( (status == -1) && (lstatus == -1) )
+ if( (status == -1) && (lstatus == -1) )
{
- /*
- * This means that the file doesn't exist, or isn't accessible.
- * Sometimes this is because of NFS permissions problems.
- */
- fprintf(stderr, "Non-existant or inaccessible: %s\n",whole_path);
- return 0;
+ /*
+ * This means that the file doesn't exist, or isn't accessible.
+ * Sometimes this is because of NFS permissions problems.
+ */
+ fprintf(stderr, "Non-existant or inaccessible: %s\n",whole_path);
+ return 0;
}
- if(this_dir == root && strcmp(short_name, ".") == 0)
- root_statbuf = statbuf; /* Save this for later on */
+ if(this_dir == root && strcmp(short_name, ".") == 0)
+ root_statbuf = statbuf; /* Save this for later on */
/* We do this to make sure that the root entries are consistent */
- if(this_dir == root && strcmp(short_name, "..") == 0)
+ if(this_dir == root && strcmp(short_name, "..") == 0)
{
- statbuf = root_statbuf;
- lstatbuf = root_statbuf;
+ statbuf = root_statbuf;
+ lstatbuf = root_statbuf;
}
- if(S_ISLNK(lstatbuf.st_mode))
- {
+ if(S_ISLNK(lstatbuf.st_mode))
+ {
- /* Here we decide how to handle the symbolic links. Here
- we handle the general case - if we are not following
- links or there is an error, then we must change
- something. If RR is in use, it is easy, we let RR
- describe the file. If not, then we punt the file. */
+ /* Here we decide how to handle the symbolic links. Here
+ we handle the general case - if we are not following
+ links or there is an error, then we must change
+ something. If RR is in use, it is easy, we let RR
+ describe the file. If not, then we punt the file. */
- if((status || !follow_links))
- {
- if(use_RockRidge)
- {
- status = 0;
- statbuf.st_size = 0;
- STAT_INODE(statbuf) = UNCACHED_INODE;
- statbuf.st_dev = (dev_t) UNCACHED_DEVICE;
- statbuf.st_mode = (statbuf.st_mode & ~S_IFMT) | S_IFREG;
- } else {
- if(follow_links)
+ /* First check for the sensible follow_links option */
+ if (follow_links_sensible)
{
- fprintf(stderr,
- "Unable to stat file %s - ignoring and continuing.\n",
- whole_path);
+ /* Where does the link point to? */
+ memset (link_buf, 0, 256);
+ readlink (whole_path, link_buf, 255);
+ if (check_dirlevel (link_buf))
+ {
+ /* Treat it as a symlink */
+ if (!use_RockRidge)
+ {
+ fprintf (stderr, "Ignoring symlink %s (which wouldn't be followed)\n",
+ whole_path);
+ }
+ else
+ {
+ do_follow_links = 0;
+ if (status)
+ {
+ status = 0;
+ statbuf.st_size = 0;
+ STAT_INODE(statbuf) = UNCACHED_INODE;
+ statbuf.st_dev = (dev_t) UNCACHED_DEVICE;
+ statbuf.st_mode = (statbuf.st_mode & ~S_IFMT) | S_IFREG;
+ }
+ }
+ }
+ else
+ {
+ /* Follow the link */
+ do_follow_links = 1;
+ }
}
- else
+ else if (!follow_links_sensible)
+ do_follow_links = follow_links;
+
+ if((status || !do_follow_links))
{
- fprintf(stderr,
- "Symlink %s ignored - continuing.\n",
- whole_path);
- return 0; /* Non Rock Ridge discs - ignore all symlinks */
+ if(use_RockRidge)
+ {
+ status = 0;
+ statbuf.st_size = 0;
+ STAT_INODE(statbuf) = UNCACHED_INODE;
+ statbuf.st_dev = (dev_t) UNCACHED_DEVICE;
+ statbuf.st_mode = (statbuf.st_mode & ~S_IFMT) | S_IFREG;
+ } else {
+ if(do_follow_links)
+ {
+ fprintf(stderr,
+ "Unable to stat file %s - ignoring and continuing.\n",
+ whole_path);
+ }
+ else
+ {
+ fprintf(stderr,
+ "Symlink %s ignored - continuing.\n",
+ whole_path);
+ return 0; /* Non Rock Ridge discs - ignore all symlinks */
+ }
+ }
}
- }
- }
- /* Here we handle a different kind of case. Here we have
- a symlink, but we want to follow symlinks. If we run
- across a directory loop, then we need to pretend that
- we are not following symlinks for this file. If this
- is the first time we have seen this, then make this
- seem as if there was no symlink there in the first
- place */
+ /* Here we handle a different kind of case. Here we have
+ a symlink, but we want to follow symlinks. If we run
+ across a directory loop, then we need to pretend that
+ we are not following symlinks for this file. If this
+ is the first time we have seen this, then make this
+ seem as if there was no symlink there in the first
+ place */
- if( follow_links
- && S_ISDIR(statbuf.st_mode) )
- {
- if( strcmp(short_name, ".")
- && strcmp(short_name, "..") )
- {
- if(find_directory_hash(statbuf.st_dev, STAT_INODE(statbuf)))
+ if( do_follow_links
+ && S_ISDIR(statbuf.st_mode) )
{
- if(!use_RockRidge)
- {
- fprintf(stderr, "Already cached directory seen (%s)\n",
- whole_path);
- return 0;
- }
- statbuf.st_size = 0;
- STAT_INODE(statbuf) = UNCACHED_INODE;
- statbuf.st_dev = (dev_t) UNCACHED_DEVICE;
- statbuf.st_mode = (statbuf.st_mode & ~S_IFMT) | S_IFREG;
+ if( strcmp(short_name, ".")
+ && strcmp(short_name, "..") )
+ {
+ if(find_directory_hash(statbuf.st_dev, STAT_INODE(statbuf)))
+ {
+ if(!use_RockRidge)
+ {
+ fprintf(stderr, "Already cached directory seen (%s)\n",
+ whole_path);
+ return 0;
+ }
+ statbuf.st_size = 0;
+ STAT_INODE(statbuf) = UNCACHED_INODE;
+ statbuf.st_dev = (dev_t) UNCACHED_DEVICE;
+ statbuf.st_mode = (statbuf.st_mode & ~S_IFMT) | S_IFREG;
+ }
+ else
+ {
+ lstatbuf = statbuf;
+ add_directory_hash(statbuf.st_dev, STAT_INODE(statbuf));
+ }
+ }
}
- else
+
+ /*
+ * For non-directories, we just copy the stat information over
+ * so we correctly include this file.
+ */
+ if( do_follow_links
+ && !S_ISDIR(statbuf.st_mode) )
{
- lstatbuf = statbuf;
- add_directory_hash(statbuf.st_dev, STAT_INODE(statbuf));
+ lstatbuf = statbuf;
}
- }
- }
-
- /*
- * For non-directories, we just copy the stat information over
- * so we correctly include this file.
- */
- if( follow_links
- && !S_ISDIR(statbuf.st_mode) )
- {
- lstatbuf = statbuf;
- }
}
/*
* Add directories to the cache so that we don't waste space even
* if we are supposed to be following symlinks.
*/
- if( follow_links
+ if( do_follow_links
&& strcmp(short_name, ".")
&& strcmp(short_name, "..")
&& S_ISDIR(statbuf.st_mode) )
@@ -1158,7 +1212,7 @@
/* Add this so that we can detect directory loops with hard links.
If we are set up to follow symlinks, then we skip this checking. */
- if( !follow_links
+ if( !do_follow_links
&& S_ISDIR(lstatbuf.st_mode)
&& strcmp(short_name, ".")
&& strcmp(short_name, "..") )