xref: /openbsd/gnu/usr.bin/cvs/src/classify.c (revision 2286d8ed)
11e72d8d2Sderaadt /*
21e72d8d2Sderaadt  * Copyright (c) 1992, Brian Berliner and Jeff Polk
31e72d8d2Sderaadt  * Copyright (c) 1989-1992, Brian Berliner
41e72d8d2Sderaadt  *
51e72d8d2Sderaadt  * You may distribute under the terms of the GNU General Public License as
6*2286d8edStholo  * specified in the README file that comes with the CVS source distribution.
71e72d8d2Sderaadt  *
81e72d8d2Sderaadt  */
91e72d8d2Sderaadt 
101e72d8d2Sderaadt #include "cvs.h"
111e72d8d2Sderaadt 
12*2286d8edStholo static void sticky_ck PROTO ((struct file_info *finfo, int aflag,
13*2286d8edStholo 			      Vers_TS * vers));
141e72d8d2Sderaadt 
151e72d8d2Sderaadt /*
161e72d8d2Sderaadt  * Classify the state of a file
171e72d8d2Sderaadt  */
181e72d8d2Sderaadt Ctype
1950bf276cStholo Classify_File (finfo, tag, date, options, force_tag_match, aflag, versp,
2050bf276cStholo 	       pipeout)
2150bf276cStholo     struct file_info *finfo;
221e72d8d2Sderaadt     char *tag;
231e72d8d2Sderaadt     char *date;
24*2286d8edStholo 
25*2286d8edStholo     /* Keyword expansion options.  Can be either NULL or "" to
26*2286d8edStholo        indicate none are specified here.  */
271e72d8d2Sderaadt     char *options;
28*2286d8edStholo 
291e72d8d2Sderaadt     int force_tag_match;
301e72d8d2Sderaadt     int aflag;
311e72d8d2Sderaadt     Vers_TS **versp;
321e72d8d2Sderaadt     int pipeout;
331e72d8d2Sderaadt {
341e72d8d2Sderaadt     Vers_TS *vers;
351e72d8d2Sderaadt     Ctype ret;
361e72d8d2Sderaadt 
371e72d8d2Sderaadt     /* get all kinds of good data about the file */
3850bf276cStholo     vers = Version_TS (finfo, options, tag, date,
3950bf276cStholo 		       force_tag_match, 0);
401e72d8d2Sderaadt 
411e72d8d2Sderaadt     if (vers->vn_user == NULL)
421e72d8d2Sderaadt     {
431e72d8d2Sderaadt 	/* No entry available, ts_rcs is invalid */
441e72d8d2Sderaadt 	if (vers->vn_rcs == NULL)
451e72d8d2Sderaadt 	{
461e72d8d2Sderaadt 	    /* there is no RCS file either */
471e72d8d2Sderaadt 	    if (vers->ts_user == NULL)
481e72d8d2Sderaadt 	    {
491e72d8d2Sderaadt 		/* there is no user file */
50b78423f6Stholo 		/* FIXME: Why do we skip this message if vers->tag or
51b78423f6Stholo 		   vers->date is set?  It causes "cvs update -r tag98 foo"
52b78423f6Stholo 		   to silently do nothing, which is seriously confusing
53b78423f6Stholo 		   behavior.  "cvs update foo" gives this message, which
54b78423f6Stholo 		   is what I would expect.  */
551e72d8d2Sderaadt 		if (!force_tag_match || !(vers->tag || vers->date))
561e72d8d2Sderaadt 		    if (!really_quiet)
5750bf276cStholo 			error (0, 0, "nothing known about %s", finfo->fullname);
581e72d8d2Sderaadt 		ret = T_UNKNOWN;
591e72d8d2Sderaadt 	    }
601e72d8d2Sderaadt 	    else
611e72d8d2Sderaadt 	    {
621e72d8d2Sderaadt 		/* there is a user file */
63b78423f6Stholo 		/* FIXME: Why do we skip this message if vers->tag or
64b78423f6Stholo 		   vers->date is set?  It causes "cvs update -r tag98 foo"
65b78423f6Stholo 		   to silently do nothing, which is seriously confusing
66b78423f6Stholo 		   behavior.  "cvs update foo" gives this message, which
67b78423f6Stholo 		   is what I would expect.  */
681e72d8d2Sderaadt 		if (!force_tag_match || !(vers->tag || vers->date))
691e72d8d2Sderaadt 		    if (!really_quiet)
70*2286d8edStholo 			error (0, 0, "use `%s add' to create an entry for %s",
71*2286d8edStholo 			       program_name, finfo->fullname);
721e72d8d2Sderaadt 		ret = T_UNKNOWN;
731e72d8d2Sderaadt 	    }
741e72d8d2Sderaadt 	}
751e72d8d2Sderaadt 	else if (RCS_isdead (vers->srcfile, vers->vn_rcs))
761e72d8d2Sderaadt 	{
771e72d8d2Sderaadt 	    if (vers->ts_user == NULL)
7850bf276cStholo 		ret = T_UPTODATE;
791e72d8d2Sderaadt 	    else
801e72d8d2Sderaadt 	    {
81*2286d8edStholo 		error (0, 0, "use `%s add' to create an entry for %s",
82*2286d8edStholo 		       program_name, finfo->fullname);
831e72d8d2Sderaadt 		ret = T_UNKNOWN;
841e72d8d2Sderaadt 	    }
851e72d8d2Sderaadt 	}
861e72d8d2Sderaadt 	else
871e72d8d2Sderaadt 	{
881e72d8d2Sderaadt 	    /* there is an rcs file */
891e72d8d2Sderaadt 
901e72d8d2Sderaadt 	    if (vers->ts_user == NULL)
911e72d8d2Sderaadt 	    {
921e72d8d2Sderaadt 		/* There is no user file; needs checkout */
931e72d8d2Sderaadt 		ret = T_CHECKOUT;
941e72d8d2Sderaadt 	    }
951e72d8d2Sderaadt 	    else
961e72d8d2Sderaadt 	    {
971e72d8d2Sderaadt 		if (pipeout)
981e72d8d2Sderaadt 		{
991e72d8d2Sderaadt 		    /*
1001e72d8d2Sderaadt 		     * The user file doesn't necessarily have anything
1011e72d8d2Sderaadt 		     * to do with this.
1021e72d8d2Sderaadt 		     */
1031e72d8d2Sderaadt 		    ret = T_CHECKOUT;
1041e72d8d2Sderaadt 		}
1051e72d8d2Sderaadt 		/*
1061e72d8d2Sderaadt 		 * There is a user file; print a warning and add it to the
1071e72d8d2Sderaadt 		 * conflict list, only if it is indeed different from what we
1081e72d8d2Sderaadt 		 * plan to extract
1091e72d8d2Sderaadt 		 */
11050bf276cStholo 		else if (No_Difference (finfo, vers))
1111e72d8d2Sderaadt 		{
1121e72d8d2Sderaadt 		    /* the files were different so it is a conflict */
1131e72d8d2Sderaadt 		    if (!really_quiet)
1141e72d8d2Sderaadt 			error (0, 0, "move away %s; it is in the way",
11550bf276cStholo 			       finfo->fullname);
1161e72d8d2Sderaadt 		    ret = T_CONFLICT;
1171e72d8d2Sderaadt 		}
1181e72d8d2Sderaadt 		else
1191e72d8d2Sderaadt 		    /* since there was no difference, still needs checkout */
1201e72d8d2Sderaadt 		    ret = T_CHECKOUT;
1211e72d8d2Sderaadt 	    }
1221e72d8d2Sderaadt 	}
1231e72d8d2Sderaadt     }
1241e72d8d2Sderaadt     else if (strcmp (vers->vn_user, "0") == 0)
1251e72d8d2Sderaadt     {
1261e72d8d2Sderaadt 	/* An entry for a new-born file; ts_rcs is dummy */
1271e72d8d2Sderaadt 
1281e72d8d2Sderaadt 	if (vers->ts_user == NULL)
1291e72d8d2Sderaadt 	{
1301e72d8d2Sderaadt 	    /*
1311e72d8d2Sderaadt 	     * There is no user file, but there should be one; remove the
1321e72d8d2Sderaadt 	     * entry
1331e72d8d2Sderaadt 	     */
1341e72d8d2Sderaadt 	    if (!really_quiet)
13550bf276cStholo 		error (0, 0, "warning: new-born %s has disappeared", finfo->fullname);
1361e72d8d2Sderaadt 	    ret = T_REMOVE_ENTRY;
1371e72d8d2Sderaadt 	}
1381e72d8d2Sderaadt 	else
1391e72d8d2Sderaadt 	{
1401e72d8d2Sderaadt 	    /* There is a user file */
1411e72d8d2Sderaadt 
1421e72d8d2Sderaadt 	    if (vers->vn_rcs == NULL)
1431e72d8d2Sderaadt 		/* There is no RCS file, added file */
1441e72d8d2Sderaadt 		ret = T_ADDED;
1451e72d8d2Sderaadt 	    else if (RCS_isdead (vers->srcfile, vers->vn_rcs))
1461e72d8d2Sderaadt 		/* we are resurrecting. */
1471e72d8d2Sderaadt 		ret = T_ADDED;
1481e72d8d2Sderaadt 	    else
1491e72d8d2Sderaadt 	    {
1501e72d8d2Sderaadt 		if (vers->srcfile->flags & INATTIC
1511e72d8d2Sderaadt 		    && vers->srcfile->flags & VALID)
1521e72d8d2Sderaadt 		{
1531e72d8d2Sderaadt 		    /* This file has been added on some branch other than
1541e72d8d2Sderaadt 		       the one we are looking at.  In the branch we are
1551e72d8d2Sderaadt 		       looking at, the file was already valid.  */
1561e72d8d2Sderaadt 		    if (!really_quiet)
1571e72d8d2Sderaadt 			error (0, 0,
158c26070a5Stholo 			       "\
159c26070a5Stholo conflict: %s has been added, but already exists",
16050bf276cStholo 			       finfo->fullname);
1611e72d8d2Sderaadt 		}
1621e72d8d2Sderaadt 		else
1631e72d8d2Sderaadt 		{
1641e72d8d2Sderaadt 		    /*
1651e72d8d2Sderaadt 		     * There is an RCS file, so someone else must have checked
1661e72d8d2Sderaadt 		     * one in behind our back; conflict
1671e72d8d2Sderaadt 		     */
1681e72d8d2Sderaadt 		    if (!really_quiet)
1691e72d8d2Sderaadt 			error (0, 0,
170c26070a5Stholo 			       "\
171c26070a5Stholo conflict: %s created independently by second party",
17250bf276cStholo 			       finfo->fullname);
1731e72d8d2Sderaadt 		}
1741e72d8d2Sderaadt 		ret = T_CONFLICT;
1751e72d8d2Sderaadt 	    }
1761e72d8d2Sderaadt 	}
1771e72d8d2Sderaadt     }
1781e72d8d2Sderaadt     else if (vers->vn_user[0] == '-')
1791e72d8d2Sderaadt     {
1801e72d8d2Sderaadt 	/* An entry for a removed file, ts_rcs is invalid */
1811e72d8d2Sderaadt 
1821e72d8d2Sderaadt 	if (vers->ts_user == NULL)
1831e72d8d2Sderaadt 	{
1841e72d8d2Sderaadt 	    /* There is no user file (as it should be) */
1851e72d8d2Sderaadt 
18650bf276cStholo 	    if (vers->vn_rcs == NULL
18750bf276cStholo 		|| RCS_isdead (vers->srcfile, vers->vn_rcs))
1881e72d8d2Sderaadt 	    {
1891e72d8d2Sderaadt 
1901e72d8d2Sderaadt 		/*
1911e72d8d2Sderaadt 		 * There is no RCS file; this is all-right, but it has been
1921e72d8d2Sderaadt 		 * removed independently by a second party; remove the entry
1931e72d8d2Sderaadt 		 */
1941e72d8d2Sderaadt 		ret = T_REMOVE_ENTRY;
1951e72d8d2Sderaadt 	    }
196461cc63eStholo 	    else if (vers->vn_rcs == NULL
197461cc63eStholo 		     ? vers->vn_user[1] == '\0'
198461cc63eStholo 		     : strcmp (vers->vn_rcs, vers->vn_user + 1) == 0)
1991e72d8d2Sderaadt 		/*
2001e72d8d2Sderaadt 		 * The RCS file is the same version as the user file was, and
2011e72d8d2Sderaadt 		 * that's OK; remove it
2021e72d8d2Sderaadt 		 */
2031e72d8d2Sderaadt 		ret = T_REMOVED;
2041e72d8d2Sderaadt 	    else
2051e72d8d2Sderaadt 	    {
2061e72d8d2Sderaadt 
2071e72d8d2Sderaadt 		/*
2081e72d8d2Sderaadt 		 * The RCS file is a newer version than the removed user file
2091e72d8d2Sderaadt 		 * and this is definitely not OK; make it a conflict.
2101e72d8d2Sderaadt 		 */
2111e72d8d2Sderaadt 		if (!really_quiet)
2121e72d8d2Sderaadt 		    error (0, 0,
2131e72d8d2Sderaadt 			   "conflict: removed %s was modified by second party",
21450bf276cStholo 			   finfo->fullname);
2151e72d8d2Sderaadt 		ret = T_CONFLICT;
2161e72d8d2Sderaadt 	    }
2171e72d8d2Sderaadt 	}
2181e72d8d2Sderaadt 	else
2191e72d8d2Sderaadt 	{
2201e72d8d2Sderaadt 	    /* The user file shouldn't be there */
2211e72d8d2Sderaadt 	    if (!really_quiet)
2221e72d8d2Sderaadt 		error (0, 0, "%s should be removed and is still there",
22350bf276cStholo 		       finfo->fullname);
2241e72d8d2Sderaadt 	    ret = T_REMOVED;
2251e72d8d2Sderaadt 	}
2261e72d8d2Sderaadt     }
2271e72d8d2Sderaadt     else
2281e72d8d2Sderaadt     {
2291e72d8d2Sderaadt 	/* A normal entry, TS_Rcs is valid */
2301e72d8d2Sderaadt 	if (vers->vn_rcs == NULL)
2311e72d8d2Sderaadt 	{
2321e72d8d2Sderaadt 	    /* There is no RCS file */
2331e72d8d2Sderaadt 
2341e72d8d2Sderaadt 	    if (vers->ts_user == NULL)
2351e72d8d2Sderaadt 	    {
2361e72d8d2Sderaadt 		/* There is no user file, so just remove the entry */
2371e72d8d2Sderaadt 		if (!really_quiet)
2381e72d8d2Sderaadt 		    error (0, 0, "warning: %s is not (any longer) pertinent",
23950bf276cStholo 			   finfo->fullname);
2401e72d8d2Sderaadt 		ret = T_REMOVE_ENTRY;
2411e72d8d2Sderaadt 	    }
2421e72d8d2Sderaadt 	    else if (strcmp (vers->ts_user, vers->ts_rcs) == 0)
2431e72d8d2Sderaadt 	    {
2441e72d8d2Sderaadt 
2451e72d8d2Sderaadt 		/*
2461e72d8d2Sderaadt 		 * The user file is still unmodified, so just remove it from
2471e72d8d2Sderaadt 		 * the entry list
2481e72d8d2Sderaadt 		 */
2491e72d8d2Sderaadt 		if (!really_quiet)
2501e72d8d2Sderaadt 		    error (0, 0, "%s is no longer in the repository",
25150bf276cStholo 			   finfo->fullname);
2521e72d8d2Sderaadt 		ret = T_REMOVE_ENTRY;
2531e72d8d2Sderaadt 	    }
2541e72d8d2Sderaadt 	    else
2551e72d8d2Sderaadt 	    {
2561e72d8d2Sderaadt 		/*
2571e72d8d2Sderaadt 		 * The user file has been modified and since it is no longer
2581e72d8d2Sderaadt 		 * in the repository, a conflict is raised
2591e72d8d2Sderaadt 		 */
26050bf276cStholo 		if (No_Difference (finfo, vers))
2611e72d8d2Sderaadt 		{
2621e72d8d2Sderaadt 		    /* they are different -> conflict */
2631e72d8d2Sderaadt 		    if (!really_quiet)
2641e72d8d2Sderaadt 			error (0, 0,
2651e72d8d2Sderaadt 	       "conflict: %s is modified but no longer in the repository",
26650bf276cStholo 			   finfo->fullname);
2671e72d8d2Sderaadt 		    ret = T_CONFLICT;
2681e72d8d2Sderaadt 		}
2691e72d8d2Sderaadt 		else
2701e72d8d2Sderaadt 		{
2711e72d8d2Sderaadt 		    /* they weren't really different */
2721e72d8d2Sderaadt 		    if (!really_quiet)
2731e72d8d2Sderaadt 			error (0, 0,
2741e72d8d2Sderaadt 			       "warning: %s is not (any longer) pertinent",
27550bf276cStholo 			       finfo->fullname);
2761e72d8d2Sderaadt 		    ret = T_REMOVE_ENTRY;
2771e72d8d2Sderaadt 		}
2781e72d8d2Sderaadt 	    }
2791e72d8d2Sderaadt 	}
2801e72d8d2Sderaadt 	else if (strcmp (vers->vn_rcs, vers->vn_user) == 0)
2811e72d8d2Sderaadt 	{
2821e72d8d2Sderaadt 	    /* The RCS file is the same version as the user file */
2831e72d8d2Sderaadt 
2841e72d8d2Sderaadt 	    if (vers->ts_user == NULL)
2851e72d8d2Sderaadt 	    {
2861e72d8d2Sderaadt 
2871e72d8d2Sderaadt 		/*
2881e72d8d2Sderaadt 		 * There is no user file, so note that it was lost and
2891e72d8d2Sderaadt 		 * extract a new version
2901e72d8d2Sderaadt 		 */
2911e72d8d2Sderaadt 		if (strcmp (command_name, "update") == 0)
2921e72d8d2Sderaadt 		    if (!really_quiet)
29350bf276cStholo 			error (0, 0, "warning: %s was lost", finfo->fullname);
2941e72d8d2Sderaadt 		ret = T_CHECKOUT;
2951e72d8d2Sderaadt 	    }
2961e72d8d2Sderaadt 	    else if (strcmp (vers->ts_user, vers->ts_rcs) == 0)
2971e72d8d2Sderaadt 	    {
2981e72d8d2Sderaadt 
2991e72d8d2Sderaadt 		/*
3001e72d8d2Sderaadt 		 * The user file is still unmodified, so nothing special at
3011e72d8d2Sderaadt 		 * all to do -- no lists updated, unless the sticky -k option
3021e72d8d2Sderaadt 		 * has changed.  If the sticky tag has changed, we just need
3031e72d8d2Sderaadt 		 * to re-register the entry
3041e72d8d2Sderaadt 		 */
3051e72d8d2Sderaadt 		if (vers->entdata->options &&
3061e72d8d2Sderaadt 		    strcmp (vers->entdata->options, vers->options) != 0)
3071e72d8d2Sderaadt 		    ret = T_CHECKOUT;
3081e72d8d2Sderaadt 		else
3091e72d8d2Sderaadt 		{
310*2286d8edStholo 		    sticky_ck (finfo, aflag, vers);
3111e72d8d2Sderaadt 		    ret = T_UPTODATE;
3121e72d8d2Sderaadt 		}
3131e72d8d2Sderaadt 	    }
3141e72d8d2Sderaadt 	    else
3151e72d8d2Sderaadt 	    {
3161e72d8d2Sderaadt 
3171e72d8d2Sderaadt 		/*
3181e72d8d2Sderaadt 		 * The user file appears to have been modified, but we call
3191e72d8d2Sderaadt 		 * No_Difference to verify that it really has been modified
3201e72d8d2Sderaadt 		 */
32150bf276cStholo 		if (No_Difference (finfo, vers))
3221e72d8d2Sderaadt 		{
3231e72d8d2Sderaadt 
3241e72d8d2Sderaadt 		    /*
3251e72d8d2Sderaadt 		     * they really are different; modified if we aren't
3261e72d8d2Sderaadt 		     * changing any sticky -k options, else needs merge
3271e72d8d2Sderaadt 		     */
3281e72d8d2Sderaadt #ifdef XXX_FIXME_WHEN_RCSMERGE_IS_FIXED
3291e72d8d2Sderaadt 		    if (strcmp (vers->entdata->options ?
3301e72d8d2Sderaadt 			   vers->entdata->options : "", vers->options) == 0)
3311e72d8d2Sderaadt 			ret = T_MODIFIED;
3321e72d8d2Sderaadt 		    else
3331e72d8d2Sderaadt 			ret = T_NEEDS_MERGE;
3341e72d8d2Sderaadt #else
3351e72d8d2Sderaadt 		    ret = T_MODIFIED;
336*2286d8edStholo 		    sticky_ck (finfo, aflag, vers);
3371e72d8d2Sderaadt #endif
3381e72d8d2Sderaadt 		}
3391e72d8d2Sderaadt 		else
3401e72d8d2Sderaadt 		{
3411e72d8d2Sderaadt 		    /* file has not changed; check out if -k changed */
3421e72d8d2Sderaadt 		    if (strcmp (vers->entdata->options ?
3431e72d8d2Sderaadt 			   vers->entdata->options : "", vers->options) != 0)
3441e72d8d2Sderaadt 		    {
3451e72d8d2Sderaadt 			ret = T_CHECKOUT;
3461e72d8d2Sderaadt 		    }
3471e72d8d2Sderaadt 		    else
3481e72d8d2Sderaadt 		    {
3491e72d8d2Sderaadt 
3501e72d8d2Sderaadt 			/*
3511e72d8d2Sderaadt 			 * else -> note that No_Difference will Register the
3521e72d8d2Sderaadt 			 * file already for us, using the new tag/date. This
3531e72d8d2Sderaadt 			 * is the desired behaviour
3541e72d8d2Sderaadt 			 */
3551e72d8d2Sderaadt 			ret = T_UPTODATE;
3561e72d8d2Sderaadt 		    }
3571e72d8d2Sderaadt 		}
3581e72d8d2Sderaadt 	    }
3591e72d8d2Sderaadt 	}
3601e72d8d2Sderaadt 	else
3611e72d8d2Sderaadt 	{
3621e72d8d2Sderaadt 	    /* The RCS file is a newer version than the user file */
3631e72d8d2Sderaadt 
3641e72d8d2Sderaadt 	    if (vers->ts_user == NULL)
3651e72d8d2Sderaadt 	    {
3661e72d8d2Sderaadt 		/* There is no user file, so just get it */
3671e72d8d2Sderaadt 
3681e72d8d2Sderaadt 		if (strcmp (command_name, "update") == 0)
3691e72d8d2Sderaadt 		    if (!really_quiet)
37050bf276cStholo 			error (0, 0, "warning: %s was lost", finfo->fullname);
3711e72d8d2Sderaadt 		ret = T_CHECKOUT;
3721e72d8d2Sderaadt 	    }
3731e72d8d2Sderaadt 	    else if (strcmp (vers->ts_user, vers->ts_rcs) == 0)
3741e72d8d2Sderaadt 	    {
3751e72d8d2Sderaadt 
3761e72d8d2Sderaadt 		/*
3771e72d8d2Sderaadt 		 * The user file is still unmodified, so just get it as well
3781e72d8d2Sderaadt 		 */
3791e72d8d2Sderaadt #ifdef SERVER_SUPPORT
3801e72d8d2Sderaadt 	        if (strcmp (vers->entdata->options ?
3811e72d8d2Sderaadt 			    vers->entdata->options : "", vers->options) != 0
3821e72d8d2Sderaadt 		    || (vers->srcfile != NULL
3831e72d8d2Sderaadt 			&& (vers->srcfile->flags & INATTIC) != 0))
3841e72d8d2Sderaadt 		    ret = T_CHECKOUT;
3851e72d8d2Sderaadt 		else
3861e72d8d2Sderaadt 		    ret = T_PATCH;
3871e72d8d2Sderaadt #else
3881e72d8d2Sderaadt 		ret = T_CHECKOUT;
3891e72d8d2Sderaadt #endif
3901e72d8d2Sderaadt 	    }
3911e72d8d2Sderaadt 	    else
3921e72d8d2Sderaadt 	    {
39350bf276cStholo 		if (No_Difference (finfo, vers))
3941e72d8d2Sderaadt 		    /* really modified, needs to merge */
3951e72d8d2Sderaadt 		    ret = T_NEEDS_MERGE;
3961e72d8d2Sderaadt #ifdef SERVER_SUPPORT
3971e72d8d2Sderaadt 	        else if ((strcmp (vers->entdata->options ?
3981e72d8d2Sderaadt 				  vers->entdata->options : "", vers->options)
3991e72d8d2Sderaadt 			  != 0)
4001e72d8d2Sderaadt 			 || (vers->srcfile != NULL
4011e72d8d2Sderaadt 			     && (vers->srcfile->flags & INATTIC) != 0))
4021e72d8d2Sderaadt 		    /* not really modified, check it out */
4031e72d8d2Sderaadt 		    ret = T_CHECKOUT;
4041e72d8d2Sderaadt 		else
4051e72d8d2Sderaadt 		    ret = T_PATCH;
4061e72d8d2Sderaadt #else
4071e72d8d2Sderaadt 		else
4081e72d8d2Sderaadt 		    /* not really modified, check it out */
4091e72d8d2Sderaadt 		    ret = T_CHECKOUT;
4101e72d8d2Sderaadt #endif
4111e72d8d2Sderaadt 	    }
4121e72d8d2Sderaadt 	}
4131e72d8d2Sderaadt     }
4141e72d8d2Sderaadt 
4151e72d8d2Sderaadt     /* free up the vers struct, or just return it */
4161e72d8d2Sderaadt     if (versp != (Vers_TS **) NULL)
4171e72d8d2Sderaadt 	*versp = vers;
4181e72d8d2Sderaadt     else
4191e72d8d2Sderaadt 	freevers_ts (&vers);
4201e72d8d2Sderaadt 
4211e72d8d2Sderaadt     /* return the status of the file */
4221e72d8d2Sderaadt     return (ret);
4231e72d8d2Sderaadt }
4241e72d8d2Sderaadt 
4251e72d8d2Sderaadt static void
426*2286d8edStholo sticky_ck (finfo, aflag, vers)
427*2286d8edStholo     struct file_info *finfo;
4281e72d8d2Sderaadt     int aflag;
4291e72d8d2Sderaadt     Vers_TS *vers;
4301e72d8d2Sderaadt {
4311e72d8d2Sderaadt     if (aflag || vers->tag || vers->date)
4321e72d8d2Sderaadt     {
4331e72d8d2Sderaadt 	char *enttag = vers->entdata->tag;
4341e72d8d2Sderaadt 	char *entdate = vers->entdata->date;
4351e72d8d2Sderaadt 
4361e72d8d2Sderaadt 	if ((enttag && vers->tag && strcmp (enttag, vers->tag)) ||
4371e72d8d2Sderaadt 	    ((enttag && !vers->tag) || (!enttag && vers->tag)) ||
4381e72d8d2Sderaadt 	    (entdate && vers->date && strcmp (entdate, vers->date)) ||
4391e72d8d2Sderaadt 	    ((entdate && !vers->date) || (!entdate && vers->date)))
4401e72d8d2Sderaadt 	{
441*2286d8edStholo 	    Register (finfo->entries, finfo->file, vers->vn_user, vers->ts_rcs,
4421e72d8d2Sderaadt 		      vers->options, vers->tag, vers->date, vers->ts_conflict);
4431e72d8d2Sderaadt 
4441e72d8d2Sderaadt #ifdef SERVER_SUPPORT
4451e72d8d2Sderaadt 	    if (server_active)
4461e72d8d2Sderaadt 	    {
4471e72d8d2Sderaadt 		/* We need to update the entries line on the client side.
4481e72d8d2Sderaadt 		   It is possible we will later update it again via
4491e72d8d2Sderaadt 		   server_updated or some such, but that is OK.  */
4501e72d8d2Sderaadt 		server_update_entries
451*2286d8edStholo 		  (finfo->file, finfo->update_dir, finfo->repository,
4521e72d8d2Sderaadt 		   strcmp (vers->ts_rcs, vers->ts_user) == 0 ?
4531e72d8d2Sderaadt 		   SERVER_UPDATED : SERVER_MERGED);
4541e72d8d2Sderaadt 	    }
4551e72d8d2Sderaadt #endif
4561e72d8d2Sderaadt 	}
4571e72d8d2Sderaadt     }
4581e72d8d2Sderaadt }
459