1/*
2 * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
3 *
4 * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
5 *                                  and others.
6 *
7 * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
8 * Portions Copyright (C) 1989-1992, Brian Berliner
9 *
10 * You may distribute under the terms of the GNU General Public License as
11 * specified in the README file that comes with the CVS source distribution.
12 *
13 * No Difference
14 *
15 * The user file looks modified judging from its time stamp; however it needn't
16 * be.  No_Difference() finds out whether it is or not. If it is not, it
17 * updates the administration.
18 *
19 * returns 0 if no differences are found and non-zero otherwise
20 */
21
22#include "cvs.h"
23#include <assert.h>
24
25int
26No_Difference (struct file_info *finfo, Vers_TS *vers)
27{
28    Node *p;
29    int ret;
30    char *ts, *options;
31    int retcode = 0;
32    char *tocvsPath;
33
34    /* If ts_user is "Is-modified", we can only conclude the files are
35       different (since we don't have the file's contents).  */
36    if (vers->ts_user != NULL
37	&& strcmp (vers->ts_user, "Is-modified") == 0)
38	return -1;
39
40    if (!vers->srcfile || !vers->srcfile->path)
41	return (-1);			/* different since we couldn't tell */
42
43#ifdef PRESERVE_PERMISSIONS_SUPPORT
44    /* If special files are in use, then any mismatch of file metadata
45       information also means that the files should be considered different. */
46    if (preserve_perms && special_file_mismatch (finfo, vers->vn_user, NULL))
47	return 1;
48#endif
49
50    if (vers->entdata && vers->entdata->options)
51	options = xstrdup (vers->entdata->options);
52    else
53	options = xstrdup ("");
54
55    tocvsPath = wrap_tocvs_process_file (finfo->file);
56    retcode = RCS_cmp_file (vers->srcfile, vers->vn_user, NULL, NULL, options,
57			    tocvsPath == NULL ? finfo->file : tocvsPath);
58    if (retcode == 0)
59    {
60	/* no difference was found, so fix the entries file */
61	ts = time_stamp (finfo->file);
62	Register (finfo->entries, finfo->file,
63		  vers->vn_user ? vers->vn_user : vers->vn_rcs, ts,
64		  options, vers->tag, vers->date, NULL);
65#ifdef SERVER_SUPPORT
66	if (server_active)
67	{
68	    /* We need to update the entries line on the client side.  */
69	    server_update_entries (finfo->file, finfo->update_dir,
70				   finfo->repository, SERVER_UPDATED);
71	}
72#endif
73	free (ts);
74
75	/* update the entdata pointer in the vers_ts structure */
76	p = findnode (finfo->entries, finfo->file);
77	assert (p);
78	vers->entdata = p->data;
79
80	ret = 0;
81    }
82    else
83	ret = 1;			/* files were really different */
84
85    if (tocvsPath)
86    {
87	/* Need to call unlink myself because the noexec variable
88	 * has been set to 1.  */
89	TRACE (TRACE_FUNCTION, "unlink (%s)", tocvsPath);
90	if ( CVS_UNLINK (tocvsPath) < 0)
91	    error (0, errno, "could not remove %s", tocvsPath);
92    }
93
94    free (options);
95    return ret;
96}
97