xref: /netbsd-src/external/gpl2/xcvs/dist/src/classify.c (revision 5a6c14c844c4c665da5632061aebde7bb2cb5766)
1a7c91847Schristos /*
2a7c91847Schristos  * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
3a7c91847Schristos  *
4a7c91847Schristos  * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
5a7c91847Schristos  *                                  and others.
6a7c91847Schristos  *
7a7c91847Schristos  * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
8a7c91847Schristos  * Portions Copyright (C) 1989-1992, Brian Berliner
9a7c91847Schristos  *
10a7c91847Schristos  * You may distribute under the terms of the GNU General Public License as
11a7c91847Schristos  * specified in the README file that comes with the CVS source distribution.
12a7c91847Schristos  *
13a7c91847Schristos  */
14*5a6c14c8Schristos #include <sys/cdefs.h>
15*5a6c14c8Schristos __RCSID("$NetBSD: classify.c,v 1.2 2016/05/17 14:00:09 christos Exp $");
16a7c91847Schristos 
17a7c91847Schristos #include "cvs.h"
18a7c91847Schristos 
19a7c91847Schristos static void sticky_ck (struct file_info *finfo, int aflag,
20a7c91847Schristos 			      Vers_TS * vers);
21a7c91847Schristos 
22a7c91847Schristos /*
23a7c91847Schristos  * Classify the state of a file.
24a7c91847Schristos  *
25a7c91847Schristos  * INPUTS
26a7c91847Schristos  *   finfo		Information about the file to be classified.
27a7c91847Schristos  *   tag
28a7c91847Schristos  *   date
29a7c91847Schristos  *   options		Keyword expansion options.  Can be either NULL or "" to
30a7c91847Schristos  *			indicate none are specified here.
31a7c91847Schristos  *   force_tag_match
32a7c91847Schristos  *   aflag
33a7c91847Schristos  *   versp
34a7c91847Schristos  *   pipeout		Did the user pass the "pipeout" flag to request that
35a7c91847Schristos  *			all output go to STDOUT rather than to a file or files?
36a7c91847Schristos  *
37a7c91847Schristos  * RETURNS
38a7c91847Schristos  *   A Ctype (defined as an enum) describing the state of the file relative to
39a7c91847Schristos  *   the repository.  See the definition of Ctype for more.
40a7c91847Schristos  */
41a7c91847Schristos Ctype
Classify_File(struct file_info * finfo,char * tag,char * date,char * options,int force_tag_match,int aflag,Vers_TS ** versp,int pipeout)42a7c91847Schristos Classify_File (struct file_info *finfo, char *tag, char *date, char *options,
43a7c91847Schristos                int force_tag_match, int aflag, Vers_TS **versp, int pipeout)
44a7c91847Schristos {
45a7c91847Schristos     Vers_TS *vers;
46a7c91847Schristos     Ctype ret;
47a7c91847Schristos 
48a7c91847Schristos     /* get all kinds of good data about the file */
49a7c91847Schristos     vers = Version_TS (finfo, options, tag, date,
50a7c91847Schristos 		       force_tag_match, 0);
51a7c91847Schristos 
52a7c91847Schristos     if (vers->vn_user == NULL)
53a7c91847Schristos     {
54a7c91847Schristos 	/* No entry available, ts_rcs is invalid */
55a7c91847Schristos 	if (vers->vn_rcs == NULL)
56a7c91847Schristos 	{
57a7c91847Schristos 	    /* there is no RCS file either */
58a7c91847Schristos 	    if (vers->ts_user == NULL)
59a7c91847Schristos 	    {
60a7c91847Schristos 		/* there is no user file */
61a7c91847Schristos 		/* FIXME: Why do we skip this message if vers->tag or
62a7c91847Schristos 		   vers->date is set?  It causes "cvs update -r tag98 foo"
63a7c91847Schristos 		   to silently do nothing, which is seriously confusing
64a7c91847Schristos 		   behavior.  "cvs update foo" gives this message, which
65a7c91847Schristos 		   is what I would expect.  */
66a7c91847Schristos 		if (!force_tag_match || !(vers->tag || vers->date))
67a7c91847Schristos 		    if (!really_quiet)
68a7c91847Schristos 			error (0, 0, "nothing known about `%s'",
69a7c91847Schristos 			       finfo->fullname);
70a7c91847Schristos 		ret = T_UNKNOWN;
71a7c91847Schristos 	    }
72a7c91847Schristos 	    else
73a7c91847Schristos 	    {
74a7c91847Schristos 		/* there is a user file */
75a7c91847Schristos 		/* FIXME: Why do we skip this message if vers->tag or
76a7c91847Schristos 		   vers->date is set?  It causes "cvs update -r tag98 foo"
77a7c91847Schristos 		   to silently do nothing, which is seriously confusing
78a7c91847Schristos 		   behavior.  "cvs update foo" gives this message, which
79a7c91847Schristos 		   is what I would expect.  */
80a7c91847Schristos 		if (!force_tag_match || !(vers->tag || vers->date))
81a7c91847Schristos 		    if (!really_quiet)
82a7c91847Schristos 			error (0, 0, "use `%s add' to create an entry for `%s'",
83a7c91847Schristos 			       program_name, finfo->fullname);
84a7c91847Schristos 		ret = T_UNKNOWN;
85a7c91847Schristos 	    }
86a7c91847Schristos 	}
87a7c91847Schristos 	else if (RCS_isdead (vers->srcfile, vers->vn_rcs))
88a7c91847Schristos 	{
89a7c91847Schristos 	    /* there is an RCS file, but it's dead */
90a7c91847Schristos 	    if (vers->ts_user == NULL)
91a7c91847Schristos 		ret = T_UPTODATE;
92a7c91847Schristos 	    else
93a7c91847Schristos 	    {
94a7c91847Schristos 		error (0, 0, "use `%s add' to create an entry for `%s'",
95a7c91847Schristos 		       program_name, finfo->fullname);
96a7c91847Schristos 		ret = T_UNKNOWN;
97a7c91847Schristos 	    }
98a7c91847Schristos 	}
99a7c91847Schristos 	else if (!pipeout && vers->ts_user && No_Difference (finfo, vers))
100a7c91847Schristos 	{
101a7c91847Schristos 	    /* the files were different so it is a conflict */
102a7c91847Schristos 	    if (!really_quiet)
103a7c91847Schristos 		error (0, 0, "move away `%s'; it is in the way",
104a7c91847Schristos 		       finfo->fullname);
105a7c91847Schristos 	    ret = T_CONFLICT;
106a7c91847Schristos 	}
107a7c91847Schristos 	else
108a7c91847Schristos 	    /* no user file or no difference, just checkout */
109a7c91847Schristos 	    ret = T_CHECKOUT;
110a7c91847Schristos     }
111a7c91847Schristos     else if (strcmp (vers->vn_user, "0") == 0)
112a7c91847Schristos     {
113a7c91847Schristos 	/* An entry for a new-born file; ts_rcs is dummy */
114a7c91847Schristos 
115a7c91847Schristos 	if (vers->ts_user == NULL)
116a7c91847Schristos 	{
117a7c91847Schristos 	    if (pipeout)
118a7c91847Schristos 	    {
119a7c91847Schristos 		ret = T_CHECKOUT;
120a7c91847Schristos 	    }
121a7c91847Schristos 	    else
122a7c91847Schristos 	    {
123a7c91847Schristos 		/*
124a7c91847Schristos 		 * There is no user file, but there should be one; remove the
125a7c91847Schristos 		 * entry
126a7c91847Schristos 		 */
127a7c91847Schristos 		if (!really_quiet)
128a7c91847Schristos 		    error (0, 0, "warning: new-born `%s' has disappeared",
129a7c91847Schristos 			   finfo->fullname);
130a7c91847Schristos 		ret = T_REMOVE_ENTRY;
131a7c91847Schristos 	    }
132a7c91847Schristos 	}
133a7c91847Schristos 	else if (vers->vn_rcs == NULL ||
134a7c91847Schristos 		 RCS_isdead (vers->srcfile, vers->vn_rcs))
135a7c91847Schristos 	    /* No RCS file or RCS file revision is dead  */
136a7c91847Schristos 	    ret = T_ADDED;
137a7c91847Schristos 	else
138a7c91847Schristos 	{
139a7c91847Schristos 	    if (pipeout)
140a7c91847Schristos 	    {
141a7c91847Schristos 		ret = T_CHECKOUT;
142a7c91847Schristos 	    }
143a7c91847Schristos 	    else
144a7c91847Schristos 	    {
145a7c91847Schristos 		if (vers->srcfile->flags & INATTIC
146a7c91847Schristos 		    && vers->srcfile->flags & VALID)
147a7c91847Schristos 		{
148a7c91847Schristos 		    /* This file has been added on some branch other than
149a7c91847Schristos 		       the one we are looking at.  In the branch we are
150a7c91847Schristos 		       looking at, the file was already valid.  */
151a7c91847Schristos 		    if (!really_quiet)
152a7c91847Schristos 			error (0, 0,
153a7c91847Schristos 			   "conflict: `%s' has been added, but already exists",
154a7c91847Schristos 			       finfo->fullname);
155a7c91847Schristos 		}
156a7c91847Schristos 		else
157a7c91847Schristos 		{
158a7c91847Schristos 		    /*
159a7c91847Schristos 		     * There is an RCS file, so someone else must have checked
160a7c91847Schristos 		     * one in behind our back; conflict
161a7c91847Schristos 		     */
162a7c91847Schristos 		    if (!really_quiet)
163a7c91847Schristos 			error (0, 0,
164a7c91847Schristos                                "conflict: `%s' created independently by"
165a7c91847Schristos 			       " second party",
166a7c91847Schristos 			       finfo->fullname);
167a7c91847Schristos 		}
168a7c91847Schristos 		ret = T_CONFLICT;
169a7c91847Schristos 	    }
170a7c91847Schristos 	}
171a7c91847Schristos     }
172a7c91847Schristos     else if (vers->vn_user[0] == '-')
173a7c91847Schristos     {
174a7c91847Schristos 	/* An entry for a removed file, ts_rcs is invalid */
175a7c91847Schristos 
176a7c91847Schristos 	if (vers->ts_user == NULL)
177a7c91847Schristos 	{
178a7c91847Schristos 	    /* There is no user file (as it should be) */
179a7c91847Schristos 
180a7c91847Schristos 	    if (vers->vn_rcs == NULL
181a7c91847Schristos 		|| RCS_isdead (vers->srcfile, vers->vn_rcs))
182a7c91847Schristos 	    {
183a7c91847Schristos 
184a7c91847Schristos 		/*
185a7c91847Schristos 		 * There is no RCS file; this is all-right, but it has been
186a7c91847Schristos 		 * removed independently by a second party; remove the entry
187a7c91847Schristos 		 */
188a7c91847Schristos 		ret = T_REMOVE_ENTRY;
189a7c91847Schristos 	    }
190a7c91847Schristos 	    else if (strcmp (vers->vn_rcs, vers->vn_user + 1) == 0)
191a7c91847Schristos 		/*
192a7c91847Schristos 		 * The RCS file is the same version as the user file was, and
193a7c91847Schristos 		 * that's OK; remove it
194a7c91847Schristos 		 */
195a7c91847Schristos 		ret = T_REMOVED;
196a7c91847Schristos 	    else if (pipeout)
197a7c91847Schristos 		/*
198a7c91847Schristos 		 * The RCS file doesn't match the user's file, but it doesn't
199a7c91847Schristos 		 * matter in this case
200a7c91847Schristos 		 */
201a7c91847Schristos 		ret = T_NEEDS_MERGE;
202a7c91847Schristos 	    else
203a7c91847Schristos 	    {
204a7c91847Schristos 
205a7c91847Schristos 		/*
206a7c91847Schristos 		 * The RCS file is a newer version than the removed user file
207a7c91847Schristos 		 * and this is definitely not OK; make it a conflict.
208a7c91847Schristos 		 */
209a7c91847Schristos 		if (!really_quiet)
210a7c91847Schristos 		    error (0, 0,
211a7c91847Schristos 			   "conflict: removed `%s' was modified by"
212a7c91847Schristos 			   " second party",
213a7c91847Schristos 			   finfo->fullname);
214a7c91847Schristos 		ret = T_CONFLICT;
215a7c91847Schristos 	    }
216a7c91847Schristos 	}
217a7c91847Schristos 	else
218a7c91847Schristos 	{
219a7c91847Schristos 	    /* The user file shouldn't be there */
220a7c91847Schristos 	    if (!really_quiet)
221a7c91847Schristos 		error (0, 0, "`%s' should be removed and is still there",
222a7c91847Schristos 		       finfo->fullname);
223a7c91847Schristos 	    ret = T_REMOVED;
224a7c91847Schristos 	}
225a7c91847Schristos     }
226a7c91847Schristos     else
227a7c91847Schristos     {
228a7c91847Schristos 	/* A normal entry, TS_Rcs is valid */
229a7c91847Schristos 	if (vers->vn_rcs == NULL || RCS_isdead (vers->srcfile, vers->vn_rcs))
230a7c91847Schristos 	{
231a7c91847Schristos 	    /* There is no RCS file */
232a7c91847Schristos 
233a7c91847Schristos 	    if (vers->ts_user == NULL)
234a7c91847Schristos 	    {
235a7c91847Schristos 		/* There is no user file, so just remove the entry */
236a7c91847Schristos 		if (!really_quiet)
237a7c91847Schristos 		    error (0, 0, "warning: `%s' is not (any longer) pertinent",
238a7c91847Schristos 			   finfo->fullname);
239a7c91847Schristos 		ret = T_REMOVE_ENTRY;
240a7c91847Schristos 	    }
241a7c91847Schristos 	    else if (strcmp (vers->ts_user, vers->ts_rcs)
242a7c91847Schristos 		     && No_Difference (finfo, vers))
243a7c91847Schristos 	    {
244a7c91847Schristos 		/* they are different -> conflict */
245a7c91847Schristos 		if (!really_quiet)
246a7c91847Schristos 		    error (0, 0,
247a7c91847Schristos                            "conflict: `%s' is modified but no longer in the"
248a7c91847Schristos 			   " repository",
249a7c91847Schristos 			   finfo->fullname);
250a7c91847Schristos 		ret = T_CONFLICT;
251a7c91847Schristos 	    }
252a7c91847Schristos 	    else
253a7c91847Schristos 	    {
254a7c91847Schristos 
255a7c91847Schristos 		/*
256a7c91847Schristos 		 * The user file is still unmodified, so just remove it from
257a7c91847Schristos 		 * the entry list
258a7c91847Schristos 		 */
259a7c91847Schristos 		if (!really_quiet)
260a7c91847Schristos 		    error (0, 0, "`%s' is no longer in the repository",
261a7c91847Schristos 			   finfo->fullname);
262a7c91847Schristos 		ret = T_REMOVE_ENTRY;
263a7c91847Schristos 	    }
264a7c91847Schristos 	}
265a7c91847Schristos 	else if (strcmp (vers->vn_rcs, vers->vn_user) == 0)
266a7c91847Schristos 	{
267a7c91847Schristos 	    /* The RCS file is the same version as the user file */
268a7c91847Schristos 
269a7c91847Schristos 	    if (vers->ts_user == NULL)
270a7c91847Schristos 	    {
271a7c91847Schristos 
272a7c91847Schristos 		/*
273a7c91847Schristos 		 * There is no user file, so note that it was lost and
274a7c91847Schristos 		 * extract a new version
275a7c91847Schristos 		 */
276a7c91847Schristos 		/* Comparing the cvs_cmd_name against "update", in
277a7c91847Schristos 		   addition to being an ugly way to operate, means
278a7c91847Schristos 		   that this message does not get printed by the
279a7c91847Schristos 		   server.  That might be considered just a straight
280a7c91847Schristos 		   bug, although there is one subtlety: that case also
281a7c91847Schristos 		   gets hit when a patch fails and the client fetches
282a7c91847Schristos 		   a file.  I'm not sure there is currently any way
283a7c91847Schristos 		   for the server to distinguish those two cases.  */
284a7c91847Schristos 		if (strcmp (cvs_cmd_name, "update") == 0)
285a7c91847Schristos 		    if (!really_quiet)
286a7c91847Schristos 			error (0, 0, "warning: `%s' was lost", finfo->fullname);
287a7c91847Schristos 		ret = T_CHECKOUT;
288a7c91847Schristos 	    }
289a7c91847Schristos 	    else if (!strcmp (vers->ts_user,
290a7c91847Schristos 			      vers->ts_conflict
291a7c91847Schristos 			      ? vers->ts_conflict : vers->ts_rcs))
292a7c91847Schristos 	    {
293a7c91847Schristos 
294a7c91847Schristos 		/*
295a7c91847Schristos 		 * The user file is still unmodified, so nothing special at
296a7c91847Schristos 		 * all to do -- no lists updated, unless the sticky -k option
297a7c91847Schristos 		 * has changed.  If the sticky tag has changed, we just need
298a7c91847Schristos 		 * to re-register the entry
299a7c91847Schristos 		 */
300a7c91847Schristos 		/* TODO: decide whether we need to check file permissions
301a7c91847Schristos 		   for a mismatch, and return T_CONFLICT if so. */
302a7c91847Schristos 		if (vers->entdata->options &&
303a7c91847Schristos 		    strcmp (vers->entdata->options, vers->options) != 0)
304a7c91847Schristos 		    ret = T_CHECKOUT;
305a7c91847Schristos 		else if (vers->ts_conflict)
306a7c91847Schristos 		    ret = T_CONFLICT;
307a7c91847Schristos 		else
308a7c91847Schristos 		{
309a7c91847Schristos 		    sticky_ck (finfo, aflag, vers);
310a7c91847Schristos 		    ret = T_UPTODATE;
311a7c91847Schristos 		}
312a7c91847Schristos 	    }
313a7c91847Schristos 	    else if (No_Difference (finfo, vers))
314a7c91847Schristos 	    {
315a7c91847Schristos 
316a7c91847Schristos 		/*
317a7c91847Schristos 		 * they really are different; modified if we aren't
318a7c91847Schristos 		 * changing any sticky -k options, else needs merge
319a7c91847Schristos 		 */
320a7c91847Schristos #ifdef XXX_FIXME_WHEN_RCSMERGE_IS_FIXED
321a7c91847Schristos 		if (strcmp (vers->entdata->options ?
322a7c91847Schristos 		       vers->entdata->options : "", vers->options) == 0)
323a7c91847Schristos 		    ret = T_MODIFIED;
324a7c91847Schristos 		else
325a7c91847Schristos 		    ret = T_NEEDS_MERGE;
326a7c91847Schristos #else
327a7c91847Schristos 		/* Files with conflict markers and new timestamps fall through
328a7c91847Schristos 		 * here, but they need to.  T_CONFLICT is an error in
329a7c91847Schristos 		 * commit_fileproc, whereas T_MODIFIED with conflict markers
330a7c91847Schristos 		 * is caught but only warned about.  Similarly, update_fileproc
331a7c91847Schristos 		 * currently reregisters a file that was conflicted but lost
332a7c91847Schristos 		 * its markers.
333a7c91847Schristos 		 */
334a7c91847Schristos 		ret = T_MODIFIED;
335a7c91847Schristos 		sticky_ck (finfo, aflag, vers);
336a7c91847Schristos #endif
337a7c91847Schristos 	    }
338a7c91847Schristos 	    else if (strcmp (vers->entdata->options ?
339a7c91847Schristos 		       vers->entdata->options : "", vers->options) != 0)
340a7c91847Schristos 	    {
341a7c91847Schristos 		/* file has not changed; check out if -k changed */
342a7c91847Schristos 		ret = T_CHECKOUT;
343a7c91847Schristos 	    }
344a7c91847Schristos 	    else
345a7c91847Schristos 	    {
346a7c91847Schristos 
347a7c91847Schristos 		/*
348a7c91847Schristos 		 * else -> note that No_Difference will Register the
349a7c91847Schristos 		 * file already for us, using the new tag/date. This
350a7c91847Schristos 		 * is the desired behaviour
351a7c91847Schristos 		 */
352a7c91847Schristos 		ret = T_UPTODATE;
353a7c91847Schristos 	    }
354a7c91847Schristos 	}
355a7c91847Schristos 	else
356a7c91847Schristos 	{
357a7c91847Schristos 	    /* The RCS file is a newer version than the user file */
358a7c91847Schristos 
359a7c91847Schristos 	    if (vers->ts_user == NULL)
360a7c91847Schristos 	    {
361a7c91847Schristos 		/* There is no user file, so just get it */
362a7c91847Schristos 
363a7c91847Schristos 		/* See comment at other "update" compare, for more
364a7c91847Schristos 		   thoughts on this comparison.  */
365a7c91847Schristos 		if (strcmp (cvs_cmd_name, "update") == 0)
366a7c91847Schristos 		    if (!really_quiet)
367a7c91847Schristos 			error (0, 0, "warning: `%s' was lost", finfo->fullname);
368a7c91847Schristos 		ret = T_CHECKOUT;
369a7c91847Schristos 	    }
370a7c91847Schristos 	    else if (strcmp (vers->ts_user, vers->ts_rcs) == 0)
371a7c91847Schristos 	    {
372a7c91847Schristos 
373a7c91847Schristos 		/*
374a7c91847Schristos 		 * The user file is still unmodified, so just get it as well
375a7c91847Schristos 		 */
376a7c91847Schristos 		if (strcmp (vers->entdata->options ?
377a7c91847Schristos 			    vers->entdata->options : "", vers->options) != 0
378a7c91847Schristos 		    || (vers->srcfile != NULL
379a7c91847Schristos 			&& (vers->srcfile->flags & INATTIC) != 0))
380a7c91847Schristos 		    ret = T_CHECKOUT;
381a7c91847Schristos 		else
382a7c91847Schristos 		    ret = T_PATCH;
383a7c91847Schristos 	    }
384a7c91847Schristos 	    else if (No_Difference (finfo, vers))
385a7c91847Schristos 		/* really modified, needs to merge */
386a7c91847Schristos 		ret = T_NEEDS_MERGE;
387a7c91847Schristos 	    else if ((strcmp (vers->entdata->options ?
388a7c91847Schristos 			      vers->entdata->options : "", vers->options)
389a7c91847Schristos 		      != 0)
390a7c91847Schristos 		     || (vers->srcfile != NULL
391a7c91847Schristos 		         && (vers->srcfile->flags & INATTIC) != 0))
392a7c91847Schristos 		/* not really modified, check it out */
393a7c91847Schristos 		ret = T_CHECKOUT;
394a7c91847Schristos 	    else
395a7c91847Schristos 		ret = T_PATCH;
396a7c91847Schristos 	}
397a7c91847Schristos     }
398a7c91847Schristos 
399a7c91847Schristos     /* free up the vers struct, or just return it */
400a7c91847Schristos     if (versp != NULL)
401a7c91847Schristos 	*versp = vers;
402a7c91847Schristos     else
403a7c91847Schristos 	freevers_ts (&vers);
404a7c91847Schristos 
405a7c91847Schristos     /* return the status of the file */
406a7c91847Schristos     return (ret);
407a7c91847Schristos }
408a7c91847Schristos 
409a7c91847Schristos static void
sticky_ck(struct file_info * finfo,int aflag,Vers_TS * vers)410a7c91847Schristos sticky_ck (struct file_info *finfo, int aflag, Vers_TS *vers)
411a7c91847Schristos {
412a7c91847Schristos     if (aflag || vers->tag || vers->date)
413a7c91847Schristos     {
414a7c91847Schristos 	char *enttag = vers->entdata->tag;
415a7c91847Schristos 	char *entdate = vers->entdata->date;
416a7c91847Schristos 
417a7c91847Schristos 	if ((enttag && vers->tag && strcmp (enttag, vers->tag)) ||
418a7c91847Schristos 	    ((enttag && !vers->tag) || (!enttag && vers->tag)) ||
419a7c91847Schristos 	    (entdate && vers->date && strcmp (entdate, vers->date)) ||
420a7c91847Schristos 	    ((entdate && !vers->date) || (!entdate && vers->date)))
421a7c91847Schristos 	{
422a7c91847Schristos 	    Register (finfo->entries, finfo->file, vers->vn_user, vers->ts_rcs,
423a7c91847Schristos 		      vers->options, vers->tag, vers->date, vers->ts_conflict);
424a7c91847Schristos 
425a7c91847Schristos #ifdef SERVER_SUPPORT
426a7c91847Schristos 	    if (server_active)
427a7c91847Schristos 	    {
428a7c91847Schristos 		/* We need to update the entries line on the client side.
429a7c91847Schristos 		   It is possible we will later update it again via
430a7c91847Schristos 		   server_updated or some such, but that is OK.  */
431a7c91847Schristos 		server_update_entries
432a7c91847Schristos 		  (finfo->file, finfo->update_dir, finfo->repository,
433a7c91847Schristos 		   strcmp (vers->ts_rcs, vers->ts_user) == 0 ?
434a7c91847Schristos 		   SERVER_UPDATED : SERVER_MERGED);
435a7c91847Schristos 	    }
436a7c91847Schristos #endif
437a7c91847Schristos 	}
438a7c91847Schristos     }
439a7c91847Schristos }
440