@@ -28,6 +28,8 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
28
28
#include <errno.h>
29
29
#include <sys/types.h>
30
30
#include <sys/file.h>
31
+ #include <sys/stat.h>
32
+ #include <sys/wait.h>
31
33
32
34
#ifdef HAVE_DIRENT_H
33
35
#include <dirent.h>
@@ -1973,6 +1975,121 @@ dbReadUse(cellDef, line, len, f, scalen, scaled, dereference, dbUseTable)
1973
1975
}
1974
1976
else if (!strcmp (cwddir , pathptr )) pathOK = TRUE;
1975
1977
1978
+ /* Apply same check as done in DBWprocs, which is to check the
1979
+ * inode of the two files and declare the path okay if they are
1980
+ * the same. This avoids conflicts in files that are referenced
1981
+ * from two different places via different relative paths, or
1982
+ * through symbolic links.
1983
+ */
1984
+
1985
+ if ((pathOK == FALSE) && strcmp (subCellDef -> cd_file , pathptr )
1986
+ && (dereference == FALSE) && (firstUse == TRUE))
1987
+ {
1988
+ struct stat statbuf ;
1989
+ ino_t inode ;
1990
+
1991
+ if (stat (subCellDef -> cd_file , & statbuf ) == 0 )
1992
+ {
1993
+ inode = statbuf .st_ino ;
1994
+
1995
+ if (stat (pathptr , & statbuf ) == 0 )
1996
+ {
1997
+ if (inode == statbuf .st_ino )
1998
+ pathOK = TRUE;
1999
+ }
2000
+ }
2001
+ }
2002
+
2003
+ if ((pathOK == FALSE) && strcmp (subCellDef -> cd_file , pathptr )
2004
+ && (dereference == FALSE) && (firstUse == TRUE))
2005
+ {
2006
+ /* See if both paths are inside a git repository, and both
2007
+ * git repositories have the same commit hash. Then the
2008
+ * two layouts can be considered equivalent. If the "git"
2009
+ * command fails for any reason, then ignore the error and
2010
+ * continue.
2011
+ */
2012
+ char * sl1ptr , * sl2ptr ;
2013
+ int link [2 ], nbytes , status ;
2014
+ pid_t pid ;
2015
+ char githash1 [128 ];
2016
+ char githash2 [128 ];
2017
+ char argstr [1024 ];
2018
+
2019
+ githash1 [0 ] = '\0' ;
2020
+
2021
+ /* Remove the file component */
2022
+ sl1ptr = strrchr (pathptr , '/' );
2023
+ if (sl1ptr != NULL ) * sl1ptr = '\0' ;
2024
+
2025
+ /* Check first file for a git hash */
2026
+ if (pipe (link ) != -1 )
2027
+ {
2028
+ FORK (pid );
2029
+ if (pid == 0 )
2030
+ {
2031
+ dup2 (link [1 ], STDOUT_FILENO );
2032
+ close (link [0 ]);
2033
+ close (link [1 ]);
2034
+ sprintf (argstr , "-C %s" , pathptr );
2035
+ execlp ("git" , argstr , "rev-parse" , "HEAD" , NULL );
2036
+ _exit (122 ); /* see vfork man page for reason for _exit() */
2037
+ }
2038
+ else
2039
+ {
2040
+ close (link [1 ]);
2041
+ nbytes = read (link [0 ], githash1 , sizeof (githash1 ));
2042
+ waitpid (pid , & status , 0 );
2043
+ }
2044
+ }
2045
+
2046
+ if (sl1ptr != NULL ) * sl1ptr = '/' ;
2047
+
2048
+ if (githash1 [0 ] != '\0' )
2049
+ {
2050
+ /* Check the second repository */
2051
+
2052
+ /* Remove the file component */
2053
+ sl2ptr = strrchr (subCellDef -> cd_file , '/' );
2054
+ if (sl2ptr != NULL ) * sl2ptr = '\0' ;
2055
+
2056
+ /* Check first file for a git hash */
2057
+ if (pipe (link ) != -1 )
2058
+ {
2059
+ FORK (pid );
2060
+ if (pid == 0 )
2061
+ {
2062
+ dup2 (link [1 ], STDOUT_FILENO );
2063
+ close (link [0 ]);
2064
+ close (link [1 ]);
2065
+ sprintf (argstr , "-C %s" , subCellDef -> cd_file );
2066
+ execlp ("git" , argstr , "rev-parse" , "HEAD" , NULL );
2067
+ _exit (123 ); /* see vfork man page for reason for _exit() */
2068
+ }
2069
+ else
2070
+ {
2071
+ close (link [1 ]);
2072
+ nbytes = read (link [0 ], githash2 , sizeof (githash2 ));
2073
+ waitpid (pid , & status , 0 );
2074
+ }
2075
+ }
2076
+
2077
+ if (sl2ptr != NULL ) * sl2ptr = '/' ;
2078
+
2079
+ if (githash2 [0 ] != '\0' )
2080
+ {
2081
+ /* Check if the repositories have the same hash */
2082
+ if (!strcmp (githash1 , githash2 ))
2083
+ {
2084
+ TxPrintf ("Cells %s in %s and %s have matching git repository"
2085
+ " commits and can be considered equivalent.\n" ,
2086
+ slashptr + 1 , subCellDef -> cd_file , pathptr );
2087
+ pathOK = TRUE;
2088
+ }
2089
+ }
2090
+ }
2091
+ }
2092
+
1976
2093
if ((pathOK == FALSE) && strcmp (subCellDef -> cd_file , pathptr )
1977
2094
&& (dereference == FALSE) && (firstUse == TRUE))
1978
2095
{
0 commit comments