xref: /openbsd-src/gnu/usr.bin/cvs/src/update.c (revision 172be96ac471deaecb64f55c313652e3887196d8)
1 /*
2  * Copyright (c) 1992, Brian Berliner and Jeff Polk
3  * Copyright (c) 1989-1992, Brian Berliner
4  *
5  * You may distribute under the terms of the GNU General Public License as
6  * specified in the README file that comes with the CVS 1.4 kit.
7  *
8  * "update" updates the version in the present directory with respect to the RCS
9  * repository.  The present version must have been created by "checkout". The
10  * user can keep up-to-date by calling "update" whenever he feels like it.
11  *
12  * The present version can be committed by "commit", but this keeps the version
13  * in tact.
14  *
15  * Arguments following the options are taken to be file names to be updated,
16  * rather than updating the entire directory.
17  *
18  * Modified or non-existent RCS files are checked out and reported as U
19  * <user_file>
20  *
21  * Modified user files are reported as M <user_file>.  If both the RCS file and
22  * the user file have been modified, the user file is replaced by the result
23  * of rcsmerge, and a backup file is written for the user in .#file.version.
24  * If this throws up irreconcilable differences, the file is reported as C
25  * <user_file>, and as M <user_file> otherwise.
26  *
27  * Files added but not yet committed are reported as A <user_file>. Files
28  * removed but not yet committed are reported as R <user_file>.
29  *
30  * If the current directory contains subdirectories that hold concurrent
31  * versions, these are updated too.  If the -d option was specified, new
32  * directories added to the repository are automatically created and updated
33  * as well.
34  */
35 
36 #include "cvs.h"
37 #include "savecwd.h"
38 #ifdef SERVER_SUPPORT
39 #include "md5.h"
40 #endif
41 #include "watch.h"
42 #include "fileattr.h"
43 #include "edit.h"
44 #include "getline.h"
45 
46 static int checkout_file PROTO ((struct file_info *finfo, Vers_TS *vers_ts,
47 				 int adding));
48 #ifdef SERVER_SUPPORT
49 static int patch_file PROTO ((struct file_info *finfo,
50 			      Vers_TS *vers_ts,
51 			      int *docheckout, struct stat *file_info,
52 			      unsigned char *checksum));
53 static void patch_file_write PROTO ((void *, const char *, size_t));
54 #endif
55 static int merge_file PROTO ((struct file_info *finfo, Vers_TS *vers));
56 static int scratch_file PROTO((struct file_info *finfo));
57 static Dtype update_dirent_proc PROTO ((void *callerdat, char *dir,
58 					char *repository, char *update_dir,
59 					List *entries));
60 static int update_dirleave_proc PROTO ((void *callerdat, char *dir,
61 					int err, char *update_dir,
62 					List *entries));
63 static int update_fileproc PROTO ((void *callerdat, struct file_info *));
64 static int update_filesdone_proc PROTO ((void *callerdat, int err,
65 					 char *repository, char *update_dir,
66 					 List *entries));
67 static int write_letter PROTO((char *file, int letter, char *update_dir));
68 #ifdef SERVER_SUPPORT
69 static void join_file PROTO ((struct file_info *finfo, Vers_TS *vers_ts));
70 #else
71 static void join_file PROTO ((struct file_info *finfo, Vers_TS *vers_ts));
72 #endif
73 
74 static char *options = NULL;
75 static char *tag = NULL;
76 static char *date = NULL;
77 /* This is a bit of a kludge.  We call WriteTag at the beginning
78    before we know whether nonbranch is set or not.  And then at the
79    end, once we have the right value for nonbranch, we call WriteTag
80    again.  I don't know whether the first call is necessary or not.
81    rewrite_tag is nonzero if we are going to have to make that second
82    call.  */
83 static int rewrite_tag;
84 static int nonbranch;
85 
86 static char *join_rev1, *date_rev1;
87 static char *join_rev2, *date_rev2;
88 static int aflag = 0;
89 static int force_tag_match = 1;
90 static int update_build_dirs = 0;
91 static int update_prune_dirs = 0;
92 static int pipeout = 0;
93 #ifdef SERVER_SUPPORT
94 static int patches = 0;
95 #endif
96 static List *ignlist = (List *) NULL;
97 static time_t last_register_time;
98 static const char *const update_usage[] =
99 {
100     "Usage: %s %s [-APdflRp] [-k kopt] [-r rev|-D date] [-j rev]\n",
101     "    [-I ign] [-W spec] [files...]\n",
102     "\t-A\tReset any sticky tags/date/kopts.\n",
103     "\t-P\tPrune empty directories.\n",
104     "\t-d\tBuild directories, like checkout does.\n",
105     "\t-f\tForce a head revision match if tag/date not found.\n",
106     "\t-l\tLocal directory only, no recursion.\n",
107     "\t-R\tProcess directories recursively.\n",
108     "\t-p\tSend updates to standard output (avoids stickiness).\n",
109     "\t-k kopt\tUse RCS kopt -k option on checkout.\n",
110     "\t-r rev\tUpdate using specified revision/tag (is sticky).\n",
111     "\t-D date\tSet date to update from (is sticky).\n",
112     "\t-j rev\tMerge in changes made between current revision and rev.\n",
113     "\t-I ign\tMore files to ignore (! to reset).\n",
114     "\t-W spec\tWrappers specification line.\n",
115     NULL
116 };
117 
118 /*
119  * update is the argv,argc based front end for arg parsing
120  */
121 int
122 update (argc, argv)
123     int argc;
124     char **argv;
125 {
126     int c, err;
127     int local = 0;			/* recursive by default */
128     int which;				/* where to look for files and dirs */
129 
130     if (argc == -1)
131 	usage (update_usage);
132 
133     ign_setup ();
134     wrap_setup ();
135 
136     /* parse the args */
137     optind = 1;
138     while ((c = getopt (argc, argv, "+ApPflRQqduk:r:D:j:I:W:")) != -1)
139     {
140 	switch (c)
141 	{
142 	    case 'A':
143 		aflag = 1;
144 		break;
145 	    case 'I':
146 		ign_add (optarg, 0);
147 		break;
148 	    case 'W':
149 		wrap_add (optarg, 0);
150 		break;
151 	    case 'k':
152 		if (options)
153 		    free (options);
154 		options = RCS_check_kflag (optarg);
155 		break;
156 	    case 'l':
157 		local = 1;
158 		break;
159 	    case 'R':
160 		local = 0;
161 		break;
162 	    case 'Q':
163 	    case 'q':
164 #ifdef SERVER_SUPPORT
165 		/* The CVS 1.5 client sends these options (in addition to
166 		   Global_option requests), so we must ignore them.  */
167 		if (!server_active)
168 #endif
169 		    error (1, 0,
170 			   "-q or -Q must be specified before \"%s\"",
171 			   command_name);
172 		break;
173 	    case 'd':
174 		update_build_dirs = 1;
175 		break;
176 	    case 'f':
177 		force_tag_match = 0;
178 		break;
179 	    case 'r':
180 		tag = optarg;
181 		break;
182 	    case 'D':
183 		date = Make_Date (optarg);
184 		break;
185 	    case 'P':
186 		update_prune_dirs = 1;
187 		break;
188 	    case 'p':
189 		pipeout = 1;
190 		noexec = 1;		/* so no locks will be created */
191 		break;
192 	    case 'j':
193 		if (join_rev2)
194 		    error (1, 0, "only two -j options can be specified");
195 		if (join_rev1)
196 		    join_rev2 = optarg;
197 		else
198 		    join_rev1 = optarg;
199 		break;
200 	    case 'u':
201 #ifdef SERVER_SUPPORT
202 		if (server_active)
203 		    patches = 1;
204 		else
205 #endif
206 		    usage (update_usage);
207 		break;
208 	    case '?':
209 	    default:
210 		usage (update_usage);
211 		break;
212 	}
213     }
214     argc -= optind;
215     argv += optind;
216 
217 #ifdef CLIENT_SUPPORT
218     if (client_active)
219     {
220 	int pass;
221 
222 	/* The first pass does the regular update.  If we receive at least
223 	   one patch which failed, we do a second pass and just fetch
224 	   those files whose patches failed.  */
225 	pass = 1;
226 	do
227 	{
228 	    int status;
229 
230 	    start_server ();
231 
232 	    if (local)
233 		send_arg("-l");
234 	    if (update_build_dirs)
235 		send_arg("-d");
236 	    if (pipeout)
237 		send_arg("-p");
238 	    if (!force_tag_match)
239 		send_arg("-f");
240 	    if (aflag)
241 		send_arg("-A");
242 	    if (update_prune_dirs)
243 		send_arg("-P");
244 	    client_prune_dirs = update_prune_dirs;
245 	    option_with_arg ("-r", tag);
246 	    if (options && options[0] != '\0')
247 		send_arg (options);
248 	    if (date)
249 		client_senddate (date);
250 	    if (join_rev1)
251 		option_with_arg ("-j", join_rev1);
252 	    if (join_rev2)
253 		option_with_arg ("-j", join_rev2);
254 	    wrap_send ();
255 
256 	    /* If the server supports the command "update-patches", that means
257 	       that it knows how to handle the -u argument to update, which
258 	       means to send patches instead of complete files.  */
259 	    if (failed_patches == NULL)
260 	    {
261 #ifndef DONT_USE_PATCH
262 		/* Systems which don't have the patch program ported to them
263 		   will want to define DONT_USE_PATCH; then CVS won't try to
264 		   invoke patch.  */
265 		if (supported_request ("update-patches"))
266 		    send_arg ("-u");
267 #endif
268 	    }
269 
270 	    if (failed_patches == NULL)
271 	    {
272 		send_file_names (argc, argv, SEND_EXPAND_WILD);
273 		/* If noexec, probably could be setting SEND_NO_CONTENTS.
274 		   Same caveats as for "cvs status" apply.  */
275 		send_files (argc, argv, local, aflag,
276 			    update_build_dirs ? SEND_BUILD_DIRS : 0);
277 	    }
278 	    else
279 	    {
280 		int i;
281 
282 		(void) printf ("%s client: refetching unpatchable files\n",
283 			       program_name);
284 
285 		if (toplevel_wd != NULL
286 		    && CVS_CHDIR (toplevel_wd) < 0)
287 		{
288 		    error (1, errno, "could not chdir to %s", toplevel_wd);
289 		}
290 
291 		for (i = 0; i < failed_patches_count; i++)
292 		    (void) unlink_file (failed_patches[i]);
293 		send_file_names (failed_patches_count, failed_patches, 0);
294 		send_files (failed_patches_count, failed_patches, local,
295 			    aflag, update_build_dirs ? SEND_BUILD_DIRS : 0);
296 	    }
297 
298 	    failed_patches = NULL;
299 	    failed_patches_count = 0;
300 
301 	    send_to_server ("update\012", 0);
302 
303 	    status = get_responses_and_close ();
304 
305 	    /* If there are any conflicts, the server will return a
306                non-zero exit status.  If any patches failed, we still
307                want to run the update again.  We use a pass count to
308                avoid an endless loop.  */
309 
310 	    /* Notes: (1) assuming that status != 0 implies a
311 	       potential conflict is the best we can cleanly do given
312 	       the current protocol.  I suppose that trying to
313 	       re-fetch in cases where there was a more serious error
314 	       is probably more or less harmless, but it isn't really
315 	       ideal.  (2) it would be nice to have a testsuite case for the
316 	       conflict-and-patch-failed case.  */
317 
318 	    if (status != 0
319 		&& (failed_patches == NULL || pass > 1))
320 	    {
321 		return status;
322 	    }
323 
324 	    ++pass;
325 	} while (failed_patches != NULL);
326 
327 	return 0;
328     }
329 #endif
330 
331     if (tag != NULL)
332 	tag_check_valid (tag, argc, argv, local, aflag, "");
333     if (join_rev1 != NULL)
334         tag_check_valid_join (join_rev1, argc, argv, local, aflag, "");
335     if (join_rev2 != NULL)
336         tag_check_valid_join (join_rev2, argc, argv, local, aflag, "");
337 
338     /*
339      * If we are updating the entire directory (for real) and building dirs
340      * as we go, we make sure there is no static entries file and write the
341      * tag file as appropriate
342      */
343     if (argc <= 0 && !pipeout)
344     {
345 	if (update_build_dirs)
346 	{
347 	    if (unlink_file (CVSADM_ENTSTAT) < 0 && ! existence_error (errno))
348 		error (1, errno, "cannot remove file %s", CVSADM_ENTSTAT);
349 #ifdef SERVER_SUPPORT
350 	    if (server_active)
351 		server_clear_entstat (".", Name_Repository (NULL, NULL));
352 #endif
353 	}
354 
355 	/* keep the CVS/Tag file current with the specified arguments */
356 	if (aflag || tag || date)
357 	{
358 	    WriteTag ((char *) NULL, tag, date, 0,
359 		      ".", Name_Repository (NULL, NULL));
360 	    rewrite_tag = 1;
361 	    nonbranch = 0;
362 	}
363     }
364 
365     /* look for files/dirs locally and in the repository */
366     which = W_LOCAL | W_REPOS;
367 
368     /* look in the attic too if a tag or date is specified */
369     if (tag != NULL || date != NULL || joining())
370 	which |= W_ATTIC;
371 
372     /* call the command line interface */
373     err = do_update (argc, argv, options, tag, date, force_tag_match,
374 		     local, update_build_dirs, aflag, update_prune_dirs,
375 		     pipeout, which, join_rev1, join_rev2, (char *) NULL);
376 
377     /* free the space Make_Date allocated if necessary */
378     if (date != NULL)
379 	free (date);
380 
381     return (err);
382 }
383 
384 /*
385  * Command line interface to update (used by checkout)
386  */
387 int
388 do_update (argc, argv, xoptions, xtag, xdate, xforce, local, xbuild, xaflag,
389 	   xprune, xpipeout, which, xjoin_rev1, xjoin_rev2, preload_update_dir)
390     int argc;
391     char **argv;
392     char *xoptions;
393     char *xtag;
394     char *xdate;
395     int xforce;
396     int local;
397     int xbuild;
398     int xaflag;
399     int xprune;
400     int xpipeout;
401     int which;
402     char *xjoin_rev1;
403     char *xjoin_rev2;
404     char *preload_update_dir;
405 {
406     int err = 0;
407     char *cp;
408 
409     /* fill in the statics */
410     options = xoptions;
411     tag = xtag;
412     date = xdate;
413     force_tag_match = xforce;
414     update_build_dirs = xbuild;
415     aflag = xaflag;
416     update_prune_dirs = xprune;
417     pipeout = xpipeout;
418 
419     /* setup the join support */
420     join_rev1 = xjoin_rev1;
421     join_rev2 = xjoin_rev2;
422     if (join_rev1 && (cp = strchr (join_rev1, ':')) != NULL)
423     {
424 	*cp++ = '\0';
425 	date_rev1 = Make_Date (cp);
426     }
427     else
428 	date_rev1 = (char *) NULL;
429     if (join_rev2 && (cp = strchr (join_rev2, ':')) != NULL)
430     {
431 	*cp++ = '\0';
432 	date_rev2 = Make_Date (cp);
433     }
434     else
435 	date_rev2 = (char *) NULL;
436 
437     /* call the recursion processor */
438     err = start_recursion (update_fileproc, update_filesdone_proc,
439 			   update_dirent_proc, update_dirleave_proc, NULL,
440 			   argc, argv, local, which, aflag, 1,
441 			   preload_update_dir, 1);
442 
443     /* see if we need to sleep before returning */
444     if (last_register_time)
445     {
446 	time_t now;
447 
448 	(void) time (&now);
449 	if (now == last_register_time)
450 	    sleep (1);			/* to avoid time-stamp races */
451     }
452 
453     return (err);
454 }
455 
456 /*
457  * This is the callback proc for update.  It is called for each file in each
458  * directory by the recursion code.  The current directory is the local
459  * instantiation.  file is the file name we are to operate on. update_dir is
460  * set to the path relative to where we started (for pretty printing).
461  * repository is the repository. entries and srcfiles are the pre-parsed
462  * entries and source control files.
463  *
464  * This routine decides what needs to be done for each file and does the
465  * appropriate magic for checkout
466  */
467 static int
468 update_fileproc (callerdat, finfo)
469     void *callerdat;
470     struct file_info *finfo;
471 {
472     int retval;
473     Ctype status;
474     Vers_TS *vers;
475     int resurrecting;
476 
477     resurrecting = 0;
478 
479     status = Classify_File (finfo, tag, date, options, force_tag_match,
480 			    aflag, &vers, pipeout);
481 
482     /* Keep track of whether TAG is a branch tag.
483        Note that if it is a branch tag in some files and a nonbranch tag
484        in others, treat it as a nonbranch tag.  It is possible that case
485        should elicit a warning or an error.  */
486     if (rewrite_tag
487 	&& tag != NULL
488 	&& finfo->rcs != NULL)
489     {
490 	char *rev = RCS_getversion (finfo->rcs, tag, NULL, 1, NULL);
491 	if (rev != NULL
492 	    && !RCS_nodeisbranch (finfo->rcs, tag))
493 	    nonbranch = 1;
494 	if (rev != NULL)
495 	    free (rev);
496     }
497 
498     if (pipeout)
499     {
500 	/*
501 	 * We just return success without doing anything if any of the really
502 	 * funky cases occur
503 	 *
504 	 * If there is still a valid RCS file, do a regular checkout type
505 	 * operation
506 	 */
507 	switch (status)
508 	{
509 	    case T_UNKNOWN:		/* unknown file was explicitly asked
510 					 * about */
511 	    case T_REMOVE_ENTRY:	/* needs to be un-registered */
512 	    case T_ADDED:		/* added but not committed */
513 		retval = 0;
514 		break;
515 	    case T_CONFLICT:		/* old punt-type errors */
516 		retval = 1;
517 		break;
518 	    case T_UPTODATE:		/* file was already up-to-date */
519 	    case T_NEEDS_MERGE:		/* needs merging */
520 	    case T_MODIFIED:		/* locally modified */
521 	    case T_REMOVED:		/* removed but not committed */
522 	    case T_CHECKOUT:		/* needs checkout */
523 #ifdef SERVER_SUPPORT
524 	    case T_PATCH:		/* needs patch */
525 #endif
526 		retval = checkout_file (finfo, vers, 0);
527 		break;
528 
529 	    default:			/* can't ever happen :-) */
530 		error (0, 0,
531 		       "unknown file status %d for file %s", status, finfo->file);
532 		retval = 0;
533 		break;
534 	}
535     }
536     else
537     {
538 	switch (status)
539 	{
540 	    case T_UNKNOWN:		/* unknown file was explicitly asked
541 					 * about */
542 	    case T_UPTODATE:		/* file was already up-to-date */
543 		retval = 0;
544 		break;
545 	    case T_CONFLICT:		/* old punt-type errors */
546 		retval = 1;
547 		(void) write_letter (finfo->file, 'C', finfo->update_dir);
548 		break;
549 	    case T_NEEDS_MERGE:		/* needs merging */
550 		if (noexec)
551 		{
552 		    retval = 1;
553 		    (void) write_letter (finfo->file, 'C', finfo->update_dir);
554 		}
555 		else
556 		{
557 		    if (wrap_merge_is_copy (finfo->file))
558 			/* Should we be warning the user that we are
559 			 * overwriting the user's copy of the file?  */
560 			retval =
561 			  checkout_file (finfo, vers, 0);
562 		    else
563 			retval = merge_file (finfo, vers);
564 		}
565 		break;
566 	    case T_MODIFIED:		/* locally modified */
567 		retval = 0;
568 		if (vers->ts_conflict)
569 		{
570 		    char *filestamp;
571 		    int retcode;
572 
573 		    /*
574 		     * If the timestamp has changed and no conflict indicators
575 		     * are found, it isn't a 'C' any more.
576 		     */
577 #ifdef SERVER_SUPPORT
578 		    if (server_active)
579 			retcode = vers->ts_conflict[0] != '=';
580 		    else {
581 			filestamp = time_stamp (finfo->file);
582 			retcode = strcmp (vers->ts_conflict, filestamp);
583 			free (filestamp);
584 		    }
585 #else
586 		    filestamp = time_stamp (finfo->file);
587 		    retcode = strcmp (vers->ts_conflict, filestamp);
588 		    free (filestamp);
589 #endif
590 
591 		    if (retcode)
592 		    {
593 			/* The timestamps differ.  But if there are conflict
594 			   markers print 'C' anyway.  */
595 			retcode = !file_has_markers (finfo);
596 		    }
597 
598 		    if (!retcode)
599 		    {
600 			(void) write_letter (finfo->file, 'C', finfo->update_dir);
601 			retval = 1;
602 		    }
603 		    else
604 		    {
605 			/* Reregister to clear conflict flag. */
606 			Register (finfo->entries, finfo->file, vers->vn_rcs, vers->ts_rcs,
607 				  vers->options, vers->tag,
608 				  vers->date, (char *)0);
609 		    }
610 		}
611 		if (!retval)
612 		    retval = write_letter (finfo->file, 'M', finfo->update_dir);
613 		break;
614 #ifdef SERVER_SUPPORT
615 	    case T_PATCH:		/* needs patch */
616 		if (patches)
617 		{
618 		    int docheckout;
619 		    struct stat file_info;
620 		    unsigned char checksum[16];
621 
622 		    retval = patch_file (finfo,
623 					 vers, &docheckout,
624 					 &file_info, checksum);
625 		    if (! docheckout)
626 		    {
627 		        if (server_active && retval == 0)
628 			    server_updated (finfo, vers,
629 					    SERVER_PATCHED, &file_info,
630 					    checksum);
631 			break;
632 		    }
633 		}
634 		/* Fall through.  */
635 		/* If we're not running as a server, just check the
636 		   file out.  It's simpler and faster than starting up
637 		   two new processes (diff and patch).  */
638 		/* Fall through.  */
639 #endif
640 	    case T_CHECKOUT:		/* needs checkout */
641 		retval = checkout_file (finfo, vers, 0);
642 #ifdef SERVER_SUPPORT
643 		if (server_active && retval == 0)
644 		    server_updated (finfo, vers,
645 				    SERVER_UPDATED, (struct stat *) NULL,
646 				    (unsigned char *) NULL);
647 #endif
648 		break;
649 	    case T_ADDED:		/* added but not committed */
650 		retval = write_letter (finfo->file, 'A', finfo->update_dir);
651 		break;
652 	    case T_REMOVED:		/* removed but not committed */
653 		retval = write_letter (finfo->file, 'R', finfo->update_dir);
654 		break;
655 	    case T_REMOVE_ENTRY:	/* needs to be un-registered */
656 		retval = scratch_file (finfo);
657 #ifdef SERVER_SUPPORT
658 		if (server_active && retval == 0)
659 		{
660 		    if (vers->ts_user == NULL)
661 			server_scratch_entry_only ();
662 		    server_updated (finfo, vers,
663 				    SERVER_UPDATED, (struct stat *) NULL,
664 				    (unsigned char *) NULL);
665 		}
666 #endif
667 		break;
668 	    default:			/* can't ever happen :-) */
669 		error (0, 0,
670 		       "unknown file status %d for file %s", status, finfo->file);
671 		retval = 0;
672 		break;
673 	}
674     }
675 
676     /* only try to join if things have gone well thus far */
677     if (retval == 0 && join_rev1)
678 	join_file (finfo, vers);
679 
680     /* if this directory has an ignore list, add this file to it */
681     if (ignlist)
682     {
683 	Node *p;
684 
685 	p = getnode ();
686 	p->type = FILES;
687 	p->key = xstrdup (finfo->file);
688 	if (addnode (ignlist, p) != 0)
689 	    freenode (p);
690     }
691 
692     freevers_ts (&vers);
693     return (retval);
694 }
695 
696 static void update_ignproc PROTO ((char *, char *));
697 
698 static void
699 update_ignproc (file, dir)
700     char *file;
701     char *dir;
702 {
703     (void) write_letter (file, '?', dir);
704 }
705 
706 /* ARGSUSED */
707 static int
708 update_filesdone_proc (callerdat, err, repository, update_dir, entries)
709     void *callerdat;
710     int err;
711     char *repository;
712     char *update_dir;
713     List *entries;
714 {
715     if (rewrite_tag)
716     {
717 	WriteTag (NULL, tag, date, nonbranch, update_dir, repository);
718 	rewrite_tag = 0;
719     }
720 
721     /* if this directory has an ignore list, process it then free it */
722     if (ignlist)
723     {
724 	ignore_files (ignlist, entries, update_dir, update_ignproc);
725 	dellist (&ignlist);
726     }
727 
728     /* Clean up CVS admin dirs if we are export */
729     if (strcmp (command_name, "export") == 0)
730     {
731 	/* I'm not sure the existence_error is actually possible (except
732 	   in cases where we really should print a message), but since
733 	   this code used to ignore all errors, I'll play it safe.  */
734 	if (unlink_file_dir (CVSADM) < 0 && !existence_error (errno))
735 	    error (0, errno, "cannot remove %s directory", CVSADM);
736     }
737 #ifdef SERVER_SUPPORT
738     else if (!server_active && !pipeout)
739 #else
740     else if (!pipeout)
741 #endif /* SERVER_SUPPORT */
742     {
743         /* If there is no CVS/Root file, add one */
744         if (!isfile (CVSADM_ROOT))
745 	    Create_Root ((char *) NULL, CVSroot_original);
746     }
747 
748     return (err);
749 }
750 
751 /*
752  * update_dirent_proc () is called back by the recursion processor before a
753  * sub-directory is processed for update.  In this case, update_dirent proc
754  * will probably create the directory unless -d isn't specified and this is a
755  * new directory.  A return code of 0 indicates the directory should be
756  * processed by the recursion code.  A return of non-zero indicates the
757  * recursion code should skip this directory.
758  */
759 static Dtype
760 update_dirent_proc (callerdat, dir, repository, update_dir, entries)
761     void *callerdat;
762     char *dir;
763     char *repository;
764     char *update_dir;
765     List *entries;
766 {
767     if (ignore_directory (update_dir))
768     {
769 	/* print the warm fuzzy message */
770 	if (!quiet)
771 	  error (0, 0, "Ignoring %s", update_dir);
772         return R_SKIP_ALL;
773     }
774 
775     if (!isdir (dir))
776     {
777 	/* if we aren't building dirs, blow it off */
778 	if (!update_build_dirs)
779 	    return (R_SKIP_ALL);
780 
781 	if (noexec)
782 	{
783 	    /* ignore the missing dir if -n is specified */
784 	    error (0, 0, "New directory `%s' -- ignored", dir);
785 	    return (R_SKIP_ALL);
786 	}
787 	else
788 	{
789 	    /* otherwise, create the dir and appropriate adm files */
790 	    make_directory (dir);
791 	    Create_Admin (dir, update_dir, repository, tag, date,
792 			  /* This is a guess.  We will rewrite it later
793 			     via WriteTag.  */
794 			  0);
795 	    rewrite_tag = 1;
796 	    nonbranch = 0;
797 	    Subdir_Register (entries, (char *) NULL, dir);
798 	}
799     }
800     /* Do we need to check noexec here? */
801     else if (!pipeout)
802     {
803 	char *cvsadmdir;
804 
805 	/* The directory exists.  Check to see if it has a CVS
806 	   subdirectory.  */
807 
808 	cvsadmdir = xmalloc (strlen (dir) + 80);
809 	strcpy (cvsadmdir, dir);
810 	strcat (cvsadmdir, "/");
811 	strcat (cvsadmdir, CVSADM);
812 
813 	if (!isdir (cvsadmdir))
814 	{
815 	    /* We cannot successfully recurse into a directory without a CVS
816 	       subdirectory.  Generally we will have already printed
817 	       "? foo".  */
818 	    free (cvsadmdir);
819 	    return R_SKIP_ALL;
820 	}
821 	free (cvsadmdir);
822     }
823 
824     /*
825      * If we are building dirs and not going to stdout, we make sure there is
826      * no static entries file and write the tag file as appropriate
827      */
828     if (!pipeout)
829     {
830 	if (update_build_dirs)
831 	{
832 	    char *tmp;
833 
834 	    tmp = xmalloc (strlen (dir) + sizeof (CVSADM_ENTSTAT) + 10);
835 	    (void) sprintf (tmp, "%s/%s", dir, CVSADM_ENTSTAT);
836 	    if (unlink_file (tmp) < 0 && ! existence_error (errno))
837 		error (1, errno, "cannot remove file %s", tmp);
838 #ifdef SERVER_SUPPORT
839 	    if (server_active)
840 		server_clear_entstat (update_dir, repository);
841 #endif
842 	    free (tmp);
843 	}
844 
845 	/* keep the CVS/Tag file current with the specified arguments */
846 	if (aflag || tag || date)
847 	{
848 	    WriteTag (dir, tag, date, 0, update_dir, repository);
849 	    rewrite_tag = 1;
850 	    nonbranch = 0;
851 	}
852 
853 	/* initialize the ignore list for this directory */
854 	ignlist = getlist ();
855     }
856 
857     /* print the warm fuzzy message */
858     if (!quiet)
859 	error (0, 0, "Updating %s", update_dir);
860 
861     return (R_PROCESS);
862 }
863 
864 /*
865  * update_dirleave_proc () is called back by the recursion code upon leaving
866  * a directory.  It will prune empty directories if needed and will execute
867  * any appropriate update programs.
868  */
869 /* ARGSUSED */
870 static int
871 update_dirleave_proc (callerdat, dir, err, update_dir, entries)
872     void *callerdat;
873     char *dir;
874     int err;
875     char *update_dir;
876     List *entries;
877 {
878     FILE *fp;
879 
880     /* run the update_prog if there is one */
881     /* FIXME: should be checking for errors from CVS_FOPEN and printing
882        them if not existence_error.  */
883     if (err == 0 && !pipeout && !noexec &&
884 	(fp = CVS_FOPEN (CVSADM_UPROG, "r")) != NULL)
885     {
886 	char *cp;
887 	char *repository;
888 	char *line = NULL;
889 	size_t line_allocated = 0;
890 
891 	repository = Name_Repository ((char *) NULL, update_dir);
892 	if (getline (&line, &line_allocated, fp) >= 0)
893 	{
894 	    if ((cp = strrchr (line, '\n')) != NULL)
895 		*cp = '\0';
896 	    run_setup ("%s %s", line, repository);
897 	    cvs_output (program_name, 0);
898 	    cvs_output (" ", 1);
899 	    cvs_output (command_name, 0);
900 	    cvs_output (": Executing '", 0);
901 	    run_print (stdout);
902 	    cvs_output ("'\n", 0);
903 	    (void) run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
904 	}
905 	else if (ferror (fp))
906 	    error (0, errno, "cannot read %s", CVSADM_UPROG);
907 	else
908 	    error (0, 0, "unexpected end of file on %s", CVSADM_UPROG);
909 
910 	if (fclose (fp) < 0)
911 	    error (0, errno, "cannot close %s", CVSADM_UPROG);
912 	if (line != NULL)
913 	    free (line);
914 	free (repository);
915     }
916 
917     if (strchr (dir, '/') == NULL)
918     {
919 	/* FIXME: chdir ("..") loses with symlinks.  */
920 	/* Prune empty dirs on the way out - if necessary */
921 	(void) CVS_CHDIR ("..");
922 	if (update_prune_dirs && isemptydir (dir, 0))
923 	{
924 	    /* I'm not sure the existence_error is actually possible (except
925 	       in cases where we really should print a message), but since
926 	       this code used to ignore all errors, I'll play it safe.	*/
927 	    if (unlink_file_dir (dir) < 0 && !existence_error (errno))
928 		error (0, errno, "cannot remove %s directory", dir);
929 	    Subdir_Deregister (entries, (char *) NULL, dir);
930 	}
931     }
932 
933     return (err);
934 }
935 
936 static int isremoved PROTO ((Node *, void *));
937 
938 /* Returns 1 if the file indicated by node has been removed.  */
939 static int
940 isremoved (node, closure)
941     Node *node;
942     void *closure;
943 {
944     Entnode *entdata = (Entnode*) node->data;
945 
946     /* If the first character of the version is a '-', the file has been
947        removed. */
948     return (entdata->version && entdata->version[0] == '-') ? 1 : 0;
949 }
950 
951 /* Returns 1 if the argument directory is completely empty, other than the
952    existence of the CVS directory entry.  Zero otherwise.  If MIGHT_NOT_EXIST
953    and the directory doesn't exist, then just return 0.  */
954 int
955 isemptydir (dir, might_not_exist)
956     char *dir;
957     int might_not_exist;
958 {
959     DIR *dirp;
960     struct dirent *dp;
961 
962     if ((dirp = CVS_OPENDIR (dir)) == NULL)
963     {
964 	if (might_not_exist && existence_error (errno))
965 	    return 0;
966 	error (0, errno, "cannot open directory %s for empty check", dir);
967 	return (0);
968     }
969     errno = 0;
970     while ((dp = readdir (dirp)) != NULL)
971     {
972 	if (strcmp (dp->d_name, ".") != 0
973 	    && strcmp (dp->d_name, "..") != 0)
974 	{
975 	    if (strcmp (dp->d_name, CVSADM) != 0)
976 	    {
977 		/* An entry other than the CVS directory.  The directory
978 		   is certainly not empty. */
979 		(void) closedir (dirp);
980 		return (0);
981 	    }
982 	    else
983 	    {
984 		/* The CVS directory entry.  We don't have to worry about
985 		   this unless the Entries file indicates that files have
986 		   been removed, but not committed, in this directory.
987 		   (Removing the directory would prevent people from
988 		   comitting the fact that they removed the files!) */
989 		List *l;
990 		int files_removed;
991 		struct saved_cwd cwd;
992 
993 		if (save_cwd (&cwd))
994 		    error_exit ();
995 
996 		if (CVS_CHDIR (dir) < 0)
997 		    error (1, errno, "cannot change directory to %s", dir);
998 		l = Entries_Open (0);
999 		files_removed = walklist (l, isremoved, 0);
1000 		Entries_Close (l);
1001 
1002 		if (restore_cwd (&cwd, NULL))
1003 		    error_exit ();
1004 		free_cwd (&cwd);
1005 
1006 		if (files_removed != 0)
1007 		{
1008 		    /* There are files that have been removed, but not
1009 		       committed!  Do not consider the directory empty. */
1010 		    (void) closedir (dirp);
1011 		    return (0);
1012 		}
1013 	    }
1014 	}
1015 	errno = 0;
1016     }
1017     if (errno != 0)
1018     {
1019 	error (0, errno, "cannot read directory %s", dir);
1020 	(void) closedir (dirp);
1021 	return (0);
1022     }
1023     (void) closedir (dirp);
1024     return (1);
1025 }
1026 
1027 /*
1028  * scratch the Entries file entry associated with a file
1029  */
1030 static int
1031 scratch_file (finfo)
1032     struct file_info *finfo;
1033 {
1034     history_write ('W', finfo->update_dir, "", finfo->file, finfo->repository);
1035     Scratch_Entry (finfo->entries, finfo->file);
1036     if (unlink_file (finfo->file) < 0 && ! existence_error (errno))
1037 	error (0, errno, "unable to remove %s", finfo->fullname);
1038     return (0);
1039 }
1040 
1041 /*
1042  * Check out a file.
1043  */
1044 static int
1045 checkout_file (finfo, vers_ts, adding)
1046     struct file_info *finfo;
1047     Vers_TS *vers_ts;
1048     int adding;
1049 {
1050     char *backup;
1051     int set_time, retval = 0;
1052     int retcode = 0;
1053     int status;
1054     int file_is_dead;
1055 
1056     /* don't screw with backup files if we're going to stdout */
1057     if (!pipeout)
1058     {
1059 	backup = xmalloc (strlen (finfo->file)
1060 			  + sizeof (CVSADM)
1061 			  + sizeof (CVSPREFIX)
1062 			  + 10);
1063 	(void) sprintf (backup, "%s/%s%s", CVSADM, CVSPREFIX, finfo->file);
1064 	if (isfile (finfo->file))
1065 	    rename_file (finfo->file, backup);
1066 	else
1067 	    /* If -f/-t wrappers are being used to wrap up a directory,
1068 	       then backup might be a directory instead of just a file.  */
1069 	    (void) unlink_file_dir (backup);
1070     }
1071 
1072     file_is_dead = RCS_isdead (vers_ts->srcfile, vers_ts->vn_rcs);
1073 
1074     if (!file_is_dead)
1075     {
1076 	/*
1077 	 * if we are checking out to stdout, print a nice message to
1078 	 * stderr, and add the -p flag to the command */
1079 	if (pipeout)
1080 	{
1081 	    if (!quiet)
1082 	    {
1083 		cvs_outerr ("\
1084 ===================================================================\n\
1085 Checking out ", 0);
1086 		cvs_outerr (finfo->fullname, 0);
1087 		cvs_outerr ("\n\
1088 RCS:  ", 0);
1089 		cvs_outerr (vers_ts->srcfile->path, 0);
1090 		cvs_outerr ("\n\
1091 VERS: ", 0);
1092 		cvs_outerr (vers_ts->vn_rcs, 0);
1093 		cvs_outerr ("\n***************\n", 0);
1094 	    }
1095 	}
1096 
1097 	status = RCS_checkout (vers_ts->srcfile,
1098 			       pipeout ? NULL : finfo->file,
1099 			       vers_ts->vn_rcs, vers_ts->vn_tag,
1100 			       vers_ts->options, RUN_TTY,
1101 			       (RCSCHECKOUTPROC) NULL, (void *) NULL);
1102     }
1103     if (file_is_dead || status == 0)
1104     {
1105 	if (!pipeout)
1106 	{
1107 	    Vers_TS *xvers_ts;
1108 
1109 	    if (cvswrite == TRUE
1110 		&& !file_is_dead
1111 		&& !fileattr_get (finfo->file, "_watched"))
1112 		xchmod (finfo->file, 1);
1113 
1114 	    {
1115 		/* A newly checked out file is never under the spell
1116 		   of "cvs edit".  If we think we were editing it
1117 		   from a previous life, clean up.  Would be better to
1118 		   check for same the working directory instead of
1119 		   same user, but that is hairy.  */
1120 
1121 		struct addremove_args args;
1122 
1123 		editor_set (finfo->file, getcaller (), NULL);
1124 
1125 		memset (&args, 0, sizeof args);
1126 		args.remove_temp = 1;
1127 		watch_modify_watchers (finfo->file, &args);
1128 	    }
1129 
1130 	    /* set the time from the RCS file iff it was unknown before */
1131 	    if (vers_ts->vn_user == NULL ||
1132 		strncmp (vers_ts->ts_rcs, "Initial", 7) == 0)
1133 	    {
1134 		set_time = 1;
1135 	    }
1136 	    else
1137 		set_time = 0;
1138 
1139 	    wrap_fromcvs_process_file (finfo->file);
1140 
1141 	    xvers_ts = Version_TS (finfo, options, tag, date,
1142 				   force_tag_match, set_time);
1143 	    if (strcmp (xvers_ts->options, "-V4") == 0)
1144 		xvers_ts->options[0] = '\0';
1145 
1146 	    (void) time (&last_register_time);
1147 
1148 	    if (file_is_dead)
1149 	    {
1150 		if (xvers_ts->vn_user != NULL)
1151 		{
1152 		    error (0, 0,
1153 			   "warning: %s is not (any longer) pertinent",
1154 			   finfo->fullname);
1155 		}
1156 		Scratch_Entry (finfo->entries, finfo->file);
1157 #ifdef SERVER_SUPPORT
1158 		if (server_active && xvers_ts->ts_user == NULL)
1159 		    server_scratch_entry_only ();
1160 #endif
1161 		/* FIXME: Rather than always unlink'ing, and ignoring the
1162 		   existence_error, we should do the unlink only if
1163 		   vers_ts->ts_user is non-NULL.  Then there would be no
1164 		   need to ignore an existence_error (for example, if the
1165 		   user removes the file while we are running).  */
1166 		if (unlink_file (finfo->file) < 0 && ! existence_error (errno))
1167 		{
1168 		    error (0, errno, "cannot remove %s", finfo->fullname);
1169 		}
1170 	    }
1171 	    else
1172 		Register (finfo->entries, finfo->file,
1173 			  adding ? "0" : xvers_ts->vn_rcs,
1174 			  xvers_ts->ts_user, xvers_ts->options,
1175 			  xvers_ts->tag, xvers_ts->date,
1176 			  (char *)0); /* Clear conflict flag on fresh checkout */
1177 
1178 	    /* fix up the vers structure, in case it is used by join */
1179 	    if (join_rev1)
1180 	    {
1181 		if (vers_ts->vn_user != NULL)
1182 		    free (vers_ts->vn_user);
1183 		if (vers_ts->vn_rcs != NULL)
1184 		    free (vers_ts->vn_rcs);
1185 		vers_ts->vn_user = xstrdup (xvers_ts->vn_rcs);
1186 		vers_ts->vn_rcs = xstrdup (xvers_ts->vn_rcs);
1187 	    }
1188 
1189 	    /* If this is really Update and not Checkout, recode history */
1190 	    if (strcmp (command_name, "update") == 0)
1191 		history_write ('U', finfo->update_dir, xvers_ts->vn_rcs, finfo->file,
1192 			       finfo->repository);
1193 
1194 	    freevers_ts (&xvers_ts);
1195 
1196 	    if (!really_quiet && !file_is_dead)
1197 	    {
1198 		write_letter (finfo->file, 'U', finfo->update_dir);
1199 	    }
1200 	}
1201     }
1202     else
1203     {
1204 	int old_errno = errno;		/* save errno value over the rename */
1205 
1206 	if (!pipeout && isfile (backup))
1207 	    rename_file (backup, finfo->file);
1208 
1209 	error (retcode == -1 ? 1 : 0, retcode == -1 ? old_errno : 0,
1210 	       "could not check out %s", finfo->fullname);
1211 
1212 	retval = retcode;
1213     }
1214 
1215     if (!pipeout)
1216     {
1217 	/* If -f/-t wrappers are being used to wrap up a directory,
1218 	   then backup might be a directory instead of just a file.  */
1219 	(void) unlink_file_dir (backup);
1220 	free (backup);
1221     }
1222 
1223     return (retval);
1224 }
1225 
1226 #ifdef SERVER_SUPPORT
1227 
1228 /* This structure is used to pass information between patch_file and
1229    patch_file_write.  */
1230 
1231 struct patch_file_data
1232 {
1233     /* File name, for error messages.  */
1234     const char *filename;
1235     /* File to which to write.  */
1236     FILE *fp;
1237     /* Whether to compute the MD5 checksum.  */
1238     int compute_checksum;
1239     /* Data structure for computing the MD5 checksum.  */
1240     struct MD5Context context;
1241     /* Set if the file has a final newline.  */
1242     int final_nl;
1243 };
1244 
1245 /* Patch a file.  Runs rcsdiff.  This is only done when running as the
1246  * server.  The hope is that the diff will be smaller than the file
1247  * itself.
1248  */
1249 static int
1250 patch_file (finfo, vers_ts, docheckout, file_info, checksum)
1251     struct file_info *finfo;
1252     Vers_TS *vers_ts;
1253     int *docheckout;
1254     struct stat *file_info;
1255     unsigned char *checksum;
1256 {
1257     char *backup;
1258     char *file1;
1259     char *file2;
1260     int retval = 0;
1261     int retcode = 0;
1262     int fail;
1263     long file_size;
1264     FILE *e;
1265     struct patch_file_data data;
1266 
1267     *docheckout = 0;
1268 
1269     if (noexec || pipeout || joining ())
1270     {
1271 	*docheckout = 1;
1272 	return 0;
1273     }
1274 
1275     /* If this file has been marked as being binary, then never send a
1276        patch.  */
1277     if (strcmp (vers_ts->options, "-kb") == 0)
1278     {
1279 	*docheckout = 1;
1280 	return 0;
1281     }
1282 
1283     backup = xmalloc (strlen (finfo->file)
1284 		      + sizeof (CVSADM)
1285 		      + sizeof (CVSPREFIX)
1286 		      + 10);
1287     (void) sprintf (backup, "%s/%s%s", CVSADM, CVSPREFIX, finfo->file);
1288     if (isfile (finfo->file))
1289         rename_file (finfo->file, backup);
1290     else
1291         (void) unlink_file (backup);
1292 
1293     file1 = xmalloc (strlen (finfo->file)
1294 		     + sizeof (CVSADM)
1295 		     + sizeof (CVSPREFIX)
1296 		     + 10);
1297     (void) sprintf (file1, "%s/%s%s-1", CVSADM, CVSPREFIX, finfo->file);
1298     file2 = xmalloc (strlen (finfo->file)
1299 		     + sizeof (CVSADM)
1300 		     + sizeof (CVSPREFIX)
1301 		     + 10);
1302     (void) sprintf (file2, "%s/%s%s-2", CVSADM, CVSPREFIX, finfo->file);
1303 
1304     fail = 0;
1305 
1306     /* We need to check out both revisions first, to see if either one
1307        has a trailing newline.  Because of this, we don't use rcsdiff,
1308        but just use diff.  */
1309 
1310     e = CVS_FOPEN (file1, "w");
1311     if (e == NULL)
1312 	error (1, errno, "cannot open %s", file1);
1313 
1314     data.filename = file1;
1315     data.fp = e;
1316     data.final_nl = 0;
1317     data.compute_checksum = 0;
1318 
1319     retcode = RCS_checkout (vers_ts->srcfile, (char *) NULL,
1320 			    vers_ts->vn_user, (char *) NULL,
1321 			    vers_ts->options, RUN_TTY,
1322 			    patch_file_write, (void *) &data);
1323 
1324     if (fclose (e) < 0)
1325 	error (1, errno, "cannot close %s", file1);
1326 
1327     if (retcode != 0 || ! data.final_nl)
1328 	fail = 1;
1329 
1330     if (! fail)
1331     {
1332 	e = CVS_FOPEN (file2, "w");
1333 	if (e == NULL)
1334 	    error (1, errno, "cannot open %s", file2);
1335 
1336 	data.filename = file2;
1337 	data.fp = e;
1338 	data.final_nl = 0;
1339 	data.compute_checksum = 1;
1340 	MD5Init (&data.context);
1341 
1342 	retcode = RCS_checkout (vers_ts->srcfile, (char *) NULL,
1343 				vers_ts->vn_rcs, (char *) NULL,
1344 				vers_ts->options, RUN_TTY,
1345 				patch_file_write, (void *) &data);
1346 
1347 	if (fclose (e) < 0)
1348 	    error (1, errno, "cannot close %s", file2);
1349 
1350 	if (retcode != 0 || ! data.final_nl)
1351 	    fail = 1;
1352 	else
1353 	    MD5Final (checksum, &data.context);
1354     }
1355 
1356     retcode = 0;
1357     if (! fail)
1358     {
1359 	/* FIXME: This whole thing with diff/patch is rather more
1360 	   convoluted than necessary (lots of forks and execs, need to
1361 	   worry about versions of diff and patch, etc.).  Also, we
1362 	   send context lines which aren't needed (in the rare case in
1363 	   which the diff doesn't apply, the checksum would catches it).
1364 	   Solution perhaps is to librarify the RCS routines which apply
1365 	   deltas or something equivalent.  */
1366 	/* This is -c, not -u, because we have no way of knowing which
1367 	   DIFF is in use.  */
1368 	run_setup ("%s -c %s %s", DIFF, file1, file2);
1369 
1370 	/* A retcode of 0 means no differences.  1 means some differences.  */
1371 	if ((retcode = run_exec (RUN_TTY, finfo->file, RUN_TTY, RUN_NORMAL)) != 0
1372 	    && retcode != 1)
1373 	{
1374 	    fail = 1;
1375 	}
1376 	else
1377 	{
1378 #define BINARY "Binary"
1379 	    char buf[sizeof BINARY];
1380 	    unsigned int c;
1381 
1382 	    /* Stat the original RCS file, and then adjust it the way
1383 	       that RCS_checkout would.  FIXME: This is an abstraction
1384 	       violation.  */
1385 	    if (CVS_STAT (vers_ts->srcfile->path, file_info) < 0)
1386 		error (1, errno, "could not stat %s", vers_ts->srcfile->path);
1387 	    if (chmod (finfo->file,
1388 		       file_info->st_mode & ~(S_IWRITE | S_IWGRP | S_IWOTH))
1389 		< 0)
1390 		error (0, errno, "cannot change mode of file %s", finfo->file);
1391 	    if (cvswrite == TRUE
1392 		&& !fileattr_get (finfo->file, "_watched"))
1393 		xchmod (finfo->file, 1);
1394 
1395 	    /* Check the diff output to make sure patch will be handle it.  */
1396 	    e = CVS_FOPEN (finfo->file, "r");
1397 	    if (e == NULL)
1398 		error (1, errno, "could not open diff output file %s",
1399 		       finfo->fullname);
1400 	    c = fread (buf, 1, sizeof BINARY - 1, e);
1401 	    buf[c] = '\0';
1402 	    if (strcmp (buf, BINARY) == 0)
1403 	    {
1404 		/* These are binary files.  We could use diff -a, but
1405 		   patch can't handle that.  */
1406 		fail = 1;
1407 	    }
1408 	    else {
1409 		/*
1410 		 * Don't send a diff if just sending the entire file
1411 		 * would be smaller
1412 		 */
1413 		fseek(e, 0L, SEEK_END);
1414 		if (file_size < ftell(e))
1415 		    fail = 1;
1416 	    }
1417 
1418 	    fclose (e);
1419 	}
1420     }
1421 
1422     if (! fail)
1423     {
1424         Vers_TS *xvers_ts;
1425 
1426         /* This stuff is just copied blindly from checkout_file.  I
1427 	   don't really know what it does.  */
1428         xvers_ts = Version_TS (finfo, options, tag, date,
1429 			       force_tag_match, 0);
1430 	if (strcmp (xvers_ts->options, "-V4") == 0)
1431 	    xvers_ts->options[0] = '\0';
1432 
1433 	Register (finfo->entries, finfo->file, xvers_ts->vn_rcs,
1434 		  xvers_ts->ts_user, xvers_ts->options,
1435 		  xvers_ts->tag, xvers_ts->date, NULL);
1436 
1437 	if (CVS_STAT (finfo->file, file_info) < 0)
1438 	    error (1, errno, "could not stat %s", finfo->file);
1439 
1440 	/* If this is really Update and not Checkout, recode history */
1441 	if (strcmp (command_name, "update") == 0)
1442 	    history_write ('P', finfo->update_dir, xvers_ts->vn_rcs, finfo->file,
1443 			   finfo->repository);
1444 
1445 	freevers_ts (&xvers_ts);
1446 
1447 	if (!really_quiet)
1448 	{
1449 	    write_letter (finfo->file, 'P', finfo->update_dir);
1450 	}
1451     }
1452     else
1453     {
1454 	int old_errno = errno;		/* save errno value over the rename */
1455 
1456 	if (isfile (backup))
1457 	    rename_file (backup, finfo->file);
1458 
1459 	if (retcode != 0 && retcode != 1)
1460 	    error (retcode == -1 ? 1 : 0, retcode == -1 ? old_errno : 0,
1461 		   "could not diff %s", finfo->fullname);
1462 
1463 	*docheckout = 1;
1464 	retval = retcode;
1465     }
1466 
1467     (void) unlink_file (backup);
1468     (void) unlink_file (file1);
1469     (void) unlink_file (file2);
1470 
1471     free (backup);
1472     free (file1);
1473     free (file2);
1474     return (retval);
1475 }
1476 
1477 /* Write data to a file.  Record whether the last byte written was a
1478    newline.  Optionally compute a checksum.  This is called by
1479    patch_file via RCS_checkout.  */
1480 
1481 static void
1482 patch_file_write (callerdat, buffer, len)
1483      void *callerdat;
1484      const char *buffer;
1485      size_t len;
1486 {
1487     struct patch_file_data *data = (struct patch_file_data *) callerdat;
1488 
1489     if (fwrite (buffer, 1, len, data->fp) != len)
1490 	error (1, errno, "cannot write %s", data->filename);
1491 
1492     data->final_nl = (buffer[len - 1] == '\n');
1493 
1494     if (data->compute_checksum)
1495 	MD5Update (&data->context, buffer, len);
1496 }
1497 
1498 #endif /* SERVER_SUPPORT */
1499 
1500 /*
1501  * Several of the types we process only print a bit of information consisting
1502  * of a single letter and the name.
1503  */
1504 static int
1505 write_letter (file, letter, update_dir)
1506     char *file;
1507     int letter;
1508     char *update_dir;
1509 {
1510     if (!really_quiet)
1511     {
1512 	char buf[2];
1513 	buf[0] = letter;
1514 	buf[1] = ' ';
1515 	cvs_output (buf, 2);
1516 	if (update_dir[0])
1517 	{
1518 	    cvs_output (update_dir, 0);
1519 	    cvs_output ("/", 1);
1520 	}
1521 	cvs_output (file, 0);
1522 	cvs_output ("\n", 1);
1523     }
1524     return (0);
1525 }
1526 
1527 /*
1528  * Do all the magic associated with a file which needs to be merged
1529  */
1530 static int
1531 merge_file (finfo, vers)
1532     struct file_info *finfo;
1533     Vers_TS *vers;
1534 {
1535     char *backup;
1536     int status;
1537     int retcode = 0;
1538     int retval;
1539 
1540     /*
1541      * The users currently modified file is moved to a backup file name
1542      * ".#filename.version", so that it will stay around for a few days
1543      * before being automatically removed by some cron daemon.  The "version"
1544      * is the version of the file that the user was most up-to-date with
1545      * before the merge.
1546      */
1547     backup = xmalloc (strlen (finfo->file)
1548 		      + strlen (vers->vn_user)
1549 		      + sizeof (BAKPREFIX)
1550 		      + 10);
1551     (void) sprintf (backup, "%s%s.%s", BAKPREFIX, finfo->file, vers->vn_user);
1552 
1553     (void) unlink_file (backup);
1554     copy_file (finfo->file, backup);
1555     xchmod (finfo->file, 1);
1556 
1557     if (strcmp (vers->options, "-kb") == 0)
1558     {
1559 	/* For binary files, a merge is always a conflict.  We give the
1560 	   user the two files, and let them resolve it.  It is possible
1561 	   that we should require a "touch foo" or similar step before
1562 	   we allow a checkin.  */
1563 	status = checkout_file (finfo, vers, 0);
1564 #ifdef SERVER_SUPPORT
1565 	/* Send the new contents of the file before the message.  If we
1566 	   wanted to be totally correct, we would have the client write
1567 	   the message only after the file has safely been written.  */
1568 	if (server_active)
1569 	{
1570 	    server_copy_file (finfo->file, finfo->update_dir,
1571 			      finfo->repository, backup);
1572 	    server_updated (finfo, vers, SERVER_MERGED,
1573 			    (struct stat *) NULL, (unsigned char *) NULL);
1574 	}
1575 #endif
1576 	error (0, 0, "binary file needs merge");
1577 	error (0, 0, "revision %s from repository is now in %s",
1578 	       vers->vn_rcs, finfo->fullname);
1579 	error (0, 0, "file from working directory is now in %s", backup);
1580 	write_letter (finfo->file, 'C', finfo->update_dir);
1581 
1582 	history_write ('C', finfo->update_dir, vers->vn_rcs, finfo->file,
1583 		       finfo->repository);
1584 	retval = 0;
1585 	goto out;
1586     }
1587 
1588     status = RCS_merge(vers->srcfile->path,
1589 		       vers->options, vers->vn_user, vers->vn_rcs);
1590     if (status != 0 && status != 1)
1591     {
1592 	error (0, status == -1 ? errno : 0,
1593 	       "could not merge revision %s of %s", vers->vn_user, finfo->fullname);
1594 	error (status == -1 ? 1 : 0, 0, "restoring %s from backup file %s",
1595 	       finfo->fullname, backup);
1596 	rename_file (backup, finfo->file);
1597 	retval = 1;
1598 	goto out;
1599     }
1600 
1601     if (strcmp (vers->options, "-V4") == 0)
1602 	vers->options[0] = '\0';
1603     (void) time (&last_register_time);
1604     {
1605 	char *cp = 0;
1606 
1607 	if (status)
1608 	    cp = time_stamp (finfo->file);
1609 	Register (finfo->entries, finfo->file, vers->vn_rcs, vers->ts_rcs, vers->options,
1610 		  vers->tag, vers->date, cp);
1611 	if (cp)
1612 	    free (cp);
1613     }
1614 
1615     /* fix up the vers structure, in case it is used by join */
1616     if (join_rev1)
1617     {
1618 	if (vers->vn_user != NULL)
1619 	    free (vers->vn_user);
1620 	vers->vn_user = xstrdup (vers->vn_rcs);
1621     }
1622 
1623 #ifdef SERVER_SUPPORT
1624     /* Send the new contents of the file before the message.  If we
1625        wanted to be totally correct, we would have the client write
1626        the message only after the file has safely been written.  */
1627     if (server_active)
1628     {
1629         server_copy_file (finfo->file, finfo->update_dir, finfo->repository,
1630 			  backup);
1631 	server_updated (finfo, vers, SERVER_MERGED,
1632 			(struct stat *) NULL, (unsigned char *) NULL);
1633     }
1634 #endif
1635 
1636     if (!noexec && !xcmp (backup, finfo->file))
1637     {
1638 	printf ("%s already contains the differences between %s and %s\n",
1639 		finfo->fullname, vers->vn_user, vers->vn_rcs);
1640 	history_write ('G', finfo->update_dir, vers->vn_rcs, finfo->file,
1641 		       finfo->repository);
1642 	retval = 0;
1643 	goto out;
1644     }
1645 
1646     if (status == 1)
1647     {
1648 	if (!noexec)
1649 	    error (0, 0, "conflicts found in %s", finfo->fullname);
1650 
1651 	write_letter (finfo->file, 'C', finfo->update_dir);
1652 
1653 	history_write ('C', finfo->update_dir, vers->vn_rcs, finfo->file, finfo->repository);
1654 
1655     }
1656     else if (retcode == -1)
1657     {
1658 	error (1, errno, "fork failed while examining update of %s",
1659 	       finfo->fullname);
1660     }
1661     else
1662     {
1663 	write_letter (finfo->file, 'M', finfo->update_dir);
1664 	history_write ('G', finfo->update_dir, vers->vn_rcs, finfo->file,
1665 		       finfo->repository);
1666     }
1667     retval = 0;
1668  out:
1669     free (backup);
1670     return retval;
1671 }
1672 
1673 /*
1674  * Do all the magic associated with a file which needs to be joined
1675  * (-j option)
1676  */
1677 static void
1678 join_file (finfo, vers)
1679     struct file_info *finfo;
1680     Vers_TS *vers;
1681 {
1682     char *backup;
1683     char *options;
1684     int status;
1685 
1686     char *rev1;
1687     char *rev2;
1688     char *jrev1;
1689     char *jrev2;
1690     char *jdate1;
1691     char *jdate2;
1692 
1693     jrev1 = join_rev1;
1694     jrev2 = join_rev2;
1695     jdate1 = date_rev1;
1696     jdate2 = date_rev2;
1697 
1698     if (wrap_merge_is_copy (finfo->file))
1699     {
1700 	error (0, 0,
1701 	       "Cannot merge %s because it is a merge-by-copy file.",
1702 	       finfo->fullname);
1703 	return;
1704     }
1705 
1706     /* Determine if we need to do anything at all.  */
1707     if (vers->srcfile == NULL ||
1708 	vers->srcfile->path == NULL)
1709     {
1710 	return;
1711     }
1712 
1713     /* If only one join revision is specified, it becomes the second
1714        revision.  */
1715     if (jrev2 == NULL)
1716     {
1717 	jrev2 = jrev1;
1718 	jrev1 = NULL;
1719 	jdate2 = jdate1;
1720 	jdate1 = NULL;
1721     }
1722 
1723     /* Convert the second revision, walking branches and dates.  */
1724     rev2 = RCS_getversion (vers->srcfile, jrev2, jdate2, 1, (int *) NULL);
1725 
1726     /* If this is a merge of two revisions, get the first revision.
1727        If only one join tag was specified, then the first revision is
1728        the greatest common ancestor of the second revision and the
1729        working file.  */
1730     if (jrev1 != NULL)
1731 	rev1 = RCS_getversion (vers->srcfile, jrev1, jdate1, 1, (int *) NULL);
1732     else
1733     {
1734 	/* Note that we use vn_rcs here, since vn_user may contain a
1735            special string such as "-nn".  */
1736 	if (vers->vn_rcs == NULL)
1737 	    rev1 = NULL;
1738 	else if (rev2 == NULL)
1739 	{
1740 	    /* This means that the file never existed on the branch.
1741                It does not mean that the file was removed on the
1742                branch: that case is represented by a dead rev2.  If
1743                the file never existed on the branch, then we have
1744                nothing to merge, so we just return.  */
1745 	    return;
1746 	}
1747 	else
1748 	    rev1 = gca (vers->vn_rcs, rev2);
1749     }
1750 
1751     /* Handle a nonexistent or dead merge target.  */
1752     if (rev2 == NULL || RCS_isdead (vers->srcfile, rev2))
1753     {
1754 	char *mrev;
1755 
1756 	if (rev2 != NULL)
1757 	    free (rev2);
1758 
1759 	/* If the first revision doesn't exist either, then there is
1760            no change between the two revisions, so we don't do
1761            anything.  */
1762 	if (rev1 == NULL || RCS_isdead (vers->srcfile, rev1))
1763 	{
1764 	    if (rev1 != NULL)
1765 		free (rev1);
1766 	    return;
1767 	}
1768 
1769 	/* If we are merging two revisions, then the file was removed
1770 	   between the first revision and the second one.  In this
1771 	   case we want to mark the file for removal.
1772 
1773 	   If we are merging one revision, then the file has been
1774 	   removed between the greatest common ancestor and the merge
1775 	   revision.  From the perspective of the branch on to which
1776 	   we ar emerging, which may be the trunk, either 1) the file
1777 	   does not currently exist on the target, or 2) the file has
1778 	   not been modified on the target branch since the greatest
1779 	   common ancestor, or 3) the file has been modified on the
1780 	   target branch since the greatest common ancestor.  In case
1781 	   1 there is nothing to do.  In case 2 we mark the file for
1782 	   removal.  In case 3 we have a conflict.
1783 
1784 	   Note that the handling is slightly different depending upon
1785 	   whether one or two join targets were specified.  If two
1786 	   join targets were specified, we don't check whether the
1787 	   file was modified since a given point.  My reasoning is
1788 	   that if you ask for an explicit merge between two tags,
1789 	   then you want to merge in whatever was changed between
1790 	   those two tags.  If a file was removed between the two
1791 	   tags, then you want it to be removed.  However, if you ask
1792 	   for a merge of a branch, then you want to merge in all
1793 	   changes which were made on the branch.  If a file was
1794 	   removed on the branch, that is a change to the file.  If
1795 	   the file was also changed on the main line, then that is
1796 	   also a change.  These two changes--the file removal and the
1797 	   modification--must be merged.  This is a conflict.  */
1798 
1799 	/* If the user file is dead, or does not exist, or has been
1800            marked for removal, then there is nothing to do.  */
1801 	if (vers->vn_user == NULL
1802 	    || vers->vn_user[0] == '-'
1803 	    || RCS_isdead (vers->srcfile, vers->vn_user))
1804 	{
1805 	    if (rev1 != NULL)
1806 		free (rev1);
1807 	    return;
1808 	}
1809 
1810 	/* If the user file has been marked for addition, or has been
1811 	   locally modified, then we have a conflict which we can not
1812 	   resolve.  No_Difference will already have been called in
1813 	   this case, so comparing the timestamps is sufficient to
1814 	   determine whether the file is locally modified.  */
1815 	if (strcmp (vers->vn_user, "0") == 0
1816 	    || (vers->ts_user != NULL
1817 		&& strcmp (vers->ts_user, vers->ts_rcs) != 0))
1818 	{
1819 	    if (jdate2 != NULL)
1820 		error (0, 0,
1821 		       "file %s is locally modified, but has been removed in revision %s as of %s",
1822 		       finfo->fullname, jrev2, jdate2);
1823 	    else
1824 		error (0, 0,
1825 		       "file %s is locally modified, but has been removed in revision %s",
1826 		       finfo->fullname, jrev2);
1827 
1828 	    /* FIXME: Should we arrange to return a non-zero exit
1829                status?  */
1830 
1831 	    if (rev1 != NULL)
1832 		free (rev1);
1833 
1834 	    return;
1835 	}
1836 
1837 	/* If only one join tag was specified, and the user file has
1838            been changed since the greatest common ancestor (rev1),
1839            then there is a conflict we can not resolve.  See above for
1840            the rationale.  */
1841 	if (join_rev2 == NULL
1842 	    && strcmp (rev1, vers->vn_user) != 0)
1843 	{
1844 	    if (jdate2 != NULL)
1845 		error (0, 0,
1846 		       "file %s has been modified, but has been removed in revision %s as of %s",
1847 		       finfo->fullname, jrev2, jdate2);
1848 	    else
1849 		error (0, 0,
1850 		       "file %s has been modified, but has been removed in revision %s",
1851 		       finfo->fullname, jrev2);
1852 
1853 	    /* FIXME: Should we arrange to return a non-zero exit
1854                status?  */
1855 
1856 	    if (rev1 != NULL)
1857 		free (rev1);
1858 
1859 	    return;
1860 	}
1861 
1862 	if (rev1 != NULL)
1863 	    free (rev1);
1864 
1865 	/* The user file exists and has not been modified.  Mark it
1866            for removal.  FIXME: If we are doing a checkout, this has
1867            the effect of first checking out the file, and then
1868            removing it.  It would be better to just register the
1869            removal.  */
1870 #ifdef SERVER_SUPPORT
1871 	if (server_active)
1872 	{
1873 	    server_scratch (finfo->file);
1874 	    server_updated (finfo, vers, SERVER_UPDATED, (struct stat *) NULL,
1875 			    (unsigned char *) NULL);
1876 	}
1877 #endif
1878 	mrev = xmalloc (strlen (vers->vn_user) + 2);
1879 	sprintf (mrev, "-%s", vers->vn_user);
1880 	Register (finfo->entries, finfo->file, mrev, vers->ts_rcs,
1881 		  vers->options, vers->tag, vers->date, vers->ts_conflict);
1882 	free (mrev);
1883 	/* We need to check existence_error here because if we are
1884            running as the server, and the file is up to date in the
1885            working directory, the client will not have sent us a copy.  */
1886 	if (unlink_file (finfo->file) < 0 && ! existence_error (errno))
1887 	    error (0, errno, "cannot remove file %s", finfo->fullname);
1888 #ifdef SERVER_SUPPORT
1889 	if (server_active)
1890 	    server_checked_in (finfo->file, finfo->update_dir,
1891 			       finfo->repository);
1892 #endif
1893 	if (! really_quiet)
1894 	    error (0, 0, "scheduling %s for removal", finfo->fullname);
1895 
1896 	return;
1897     }
1898 
1899     /* If the target of the merge is the same as the working file
1900        revision, then there is nothing to do.  */
1901     if (vers->vn_user != NULL && strcmp (rev2, vers->vn_user) == 0)
1902     {
1903 	if (rev1 != NULL)
1904 	    free (rev1);
1905 	free (rev2);
1906 	return;
1907     }
1908 
1909     /* If rev1 is dead or does not exist, then the file was added
1910        between rev1 and rev2.  */
1911     if (rev1 == NULL || RCS_isdead (vers->srcfile, rev1))
1912     {
1913 	if (rev1 != NULL)
1914 	    free (rev1);
1915 	free (rev2);
1916 
1917 	/* If the file does not exist in the working directory, then
1918            we can just check out the new revision and mark it for
1919            addition.  */
1920 	if (vers->vn_user == NULL)
1921 	{
1922 	    Vers_TS *xvers;
1923 
1924 	    xvers = Version_TS (finfo, vers->options, jrev2, jdate2, 1, 0);
1925 
1926 	    /* FIXME: If checkout_file fails, we should arrange to
1927                return a non-zero exit status.  */
1928 	    status = checkout_file (finfo, xvers, 1);
1929 
1930 #ifdef SERVER_SUPPORT
1931 	    if (server_active && status == 0)
1932 		server_updated (finfo, xvers,
1933 				SERVER_UPDATED, (struct stat *) NULL,
1934 				(unsigned char *) NULL);
1935 #endif
1936 
1937 	    freevers_ts (&xvers);
1938 
1939 	    return;
1940 	}
1941 
1942 	/* The file currently exists in the working directory, so we
1943            have a conflict which we can not resolve.  Note that this
1944            is true even if the file is marked for addition or removal.  */
1945 
1946 	if (jdate2 != NULL)
1947 	    error (0, 0,
1948 		   "file %s exists, but has been added in revision %s as of %s",
1949 		   finfo->fullname, jrev2, jdate2);
1950 	else
1951 	    error (0, 0,
1952 		   "file %s exists, but has been added in revision %s",
1953 		   finfo->fullname, jrev2);
1954 
1955 	return;
1956     }
1957 
1958     /* If the two merge revisions are the same, then there is nothing
1959        to do.  */
1960     if (strcmp (rev1, rev2) == 0)
1961     {
1962 	free (rev1);
1963 	free (rev2);
1964 	return;
1965     }
1966 
1967     /* If there is no working file, then we can't do the merge.  */
1968     if (vers->vn_user == NULL)
1969     {
1970 	free (rev1);
1971 	free (rev2);
1972 
1973 	if (jdate2 != NULL)
1974 	    error (0, 0,
1975 		   "file %s is present in revision %s as of %s",
1976 		   finfo->fullname, jrev2, jdate2);
1977 	else
1978 	    error (0, 0,
1979 		   "file %s is present in revision %s",
1980 		   finfo->fullname, jrev2);
1981 
1982 	/* FIXME: Should we arrange to return a non-zero exit status?  */
1983 
1984 	return;
1985     }
1986 
1987 #ifdef SERVER_SUPPORT
1988     if (server_active && !isreadable (finfo->file))
1989     {
1990 	int retcode;
1991 	/* The file is up to date.  Need to check out the current contents.  */
1992 	retcode = RCS_checkout (vers->srcfile, finfo->file,
1993 				vers->vn_user, (char *) NULL,
1994 				(char *) NULL, RUN_TTY,
1995 				(RCSCHECKOUTPROC) NULL, (void *) NULL);
1996 	if (retcode != 0)
1997 	    error (1, retcode == -1 ? errno : 0,
1998 		   "failed to check out %s file", finfo->fullname);
1999     }
2000 #endif
2001 
2002     /*
2003      * The users currently modified file is moved to a backup file name
2004      * ".#filename.version", so that it will stay around for a few days
2005      * before being automatically removed by some cron daemon.  The "version"
2006      * is the version of the file that the user was most up-to-date with
2007      * before the merge.
2008      */
2009     backup = xmalloc (strlen (finfo->file)
2010 		      + strlen (vers->vn_user)
2011 		      + sizeof (BAKPREFIX)
2012 		      + 10);
2013     (void) sprintf (backup, "%s%s.%s", BAKPREFIX, finfo->file, vers->vn_user);
2014 
2015     (void) unlink_file (backup);
2016     copy_file (finfo->file, backup);
2017     xchmod (finfo->file, 1);
2018 
2019     options = vers->options;
2020 #ifdef HAVE_RCS5
2021 #if 0
2022     if (*options == '\0')
2023 	options = "-kk";		/* to ignore keyword expansions */
2024 #endif
2025 #endif
2026 
2027     status = RCS_merge (vers->srcfile->path, options, rev1, rev2);
2028     if (status != 0 && status != 1)
2029     {
2030 	error (0, status == -1 ? errno : 0,
2031 	       "could not merge revision %s of %s", rev2, finfo->fullname);
2032 	error (status == -1 ? 1 : 0, 0, "restoring %s from backup file %s",
2033 	       finfo->fullname, backup);
2034 	rename_file (backup, finfo->file);
2035     }
2036     free (rev1);
2037     free (rev2);
2038 
2039 #ifdef SERVER_SUPPORT
2040     /*
2041      * If we're in server mode, then we need to re-register the file
2042      * even if there were no conflicts (status == 0).
2043      * This tells server_updated() to send the modified file back to
2044      * the client.
2045      */
2046     if (status == 1 || (status == 0 && server_active))
2047 #else
2048     if (status == 1)
2049 #endif
2050     {
2051 	char *cp = 0;
2052 
2053 	if (status)
2054 	    cp = time_stamp (finfo->file);
2055 	Register (finfo->entries, finfo->file,
2056 		  vers->vn_rcs, vers->ts_rcs, vers->options,
2057 		  vers->tag, vers->date, cp);
2058 	if (cp)
2059 	    free(cp);
2060     }
2061 
2062 #ifdef SERVER_SUPPORT
2063     if (server_active)
2064     {
2065 	server_copy_file (finfo->file, finfo->update_dir, finfo->repository,
2066 			  backup);
2067 	server_updated (finfo, vers, SERVER_MERGED,
2068 			(struct stat *) NULL, (unsigned char *) NULL);
2069     }
2070 #endif
2071     free (backup);
2072 }
2073 
2074 int
2075 joining ()
2076 {
2077     return (join_rev1 != NULL);
2078 }
2079