include # DDIFF -- Find the differences between two directories # This procedure compares two directory trees, printing out the names of file # that are in the first directory tree but not in the second. The comparison # can be restricted by using a pattern, in which case only file names matching # the pattern in either directory will be printed out. The comparison can be # widened by setting DATE to true, in which case files in the first directory # which have a modification date later than the file with the same name in # the second are also printed out. # # B.Simon 27-Apr-89 Original # B.Simon 29-Aug-90 Changed to allow absolute pathnames procedure ddiff () #-- pointer dir1 # First directory name pointer dir2 # Second directory name pointer pattern # Only check files with the given pattern int maxdepth # Maximum depth to search directories bool date # Check dates in addition to names bool absolute # Generate absolute path names bool more1, more2 int nc, status, diff long info1[LEN_FINFO], info2[LEN_FINFO] pointer sp, template, errmsg pointer list1, list2, file1, file2, path string notdir "%s is not a directory" string noinfo "Warning: cannot access file %s" bool clgetb(), getrsearch() int clgeti(), nowhite(), finfo(), strcmp() pointer opnrsearch() begin # Allocate dynamic memory for strings call smark (sp) call salloc (dir1, SZ_FNAME, TY_CHAR) call salloc (dir2, SZ_FNAME, TY_CHAR) call salloc (pattern, SZ_FNAME, TY_CHAR) call salloc (template, SZ_PATHNAME, TY_CHAR) call salloc (file1, SZ_FNAME, TY_CHAR) call salloc (file2, SZ_FNAME, TY_CHAR) call salloc (path, SZ_PATHNAME, TY_CHAR) call salloc (errmsg, SZ_LINE, TY_CHAR) # Read task parameters, stripping blanks call clgstr ("dir1", Memc[dir1], SZ_FNAME) call clgstr ("dir2", Memc[dir2], SZ_FNAME) call clgstr ("pattern", Memc[pattern], SZ_FNAME) maxdepth = clgeti ("maxdepth") date = clgetb ("date") absolute = clgetb ("absolute") nc = nowhite (Memc[dir1], Memc[dir1], SZ_PATHNAME) nc = nowhite (Memc[dir2], Memc[dir2], SZ_PATHNAME) nc = nowhite (Memc[pattern], Memc[pattern], SZ_FNAME) # Check to see if directory names are really directories status = finfo (Memc[dir1], info1) if (status == ERR || FI_TYPE(info1) != FI_DIRECTORY) { call sprintf (Memc[errmsg], SZ_LINE, notdir) call pargstr (Memc[dir1]) call error (1, Memc[errmsg]) } status = finfo (Memc[dir2], info2) if (status == ERR || FI_TYPE(info2) != FI_DIRECTORY) { call sprintf (Memc[errmsg], SZ_LINE, notdir) call pargstr (Memc[dir2]) call error (1, Memc[errmsg]) } # Open the file name list for both directories list1 = opnrsearch (Memc[dir1], Memc[pattern], maxdepth) list2 = opnrsearch (Memc[dir2], Memc[pattern], maxdepth) # Compare both lists, printing out names from the first # directory when not present in the second more1 = getrsearch (list1, info1, Memc[file1], SZ_FNAME) more2 = getrsearch (list2, info2, Memc[file2], SZ_FNAME) while (more1 && more2) { diff = strcmp (Memc[file1], Memc[file2]) if (diff < 0) { if (absolute) { call mkpathname (Memc[dir1], Memc[file1], Memc[path], SZ_PATHNAME) call printf ("%s\n") call pargstr (Memc[path]) } else { call printf ("%s\n") call pargstr (Memc[file1]) } more1 = getrsearch (list1, info1, Memc[file1], SZ_FNAME) } else if (diff > 0) { more2 = getrsearch (list2, info2, Memc[file2], SZ_FNAME) } else { # Also check the modification date for files in the # first directory modified after the second if (date && (FI_MTIME(info1) > FI_MTIME(info2))) { if (absolute) { call mkpathname (Memc[dir1], Memc[file1], Memc[path], SZ_PATHNAME) call printf ("%s\n") call pargstr (Memc[path]) } else { call printf ("%s\n") call pargstr (Memc[file1]) } } more1 = getrsearch (list1, info1, Memc[file1], SZ_FNAME) more2 = getrsearch (list2, info2, Memc[file2], SZ_FNAME) } } # Finish up by printing remaining files in the first directory while (more1) { if (absolute) { call mkpathname (Memc[dir1], Memc[file1], Memc[path], SZ_PATHNAME) call printf ("%s\n") call pargstr (Memc[path]) } else { call printf ("%s\n") call pargstr (Memc[file1]) } more1 = getrsearch (list1, info1, Memc[file1], SZ_FNAME) } call clsrsearch (list1) call clsrsearch (list2) call sfree (sp) end