xref: /netbsd-src/external/gpl2/xcvs/dist/src/import.c (revision 413d532bcc3f62d122e56d92e13ac64825a40baf)
1 /*
2  * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
3  *
4  * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
5  *                                  and others.
6  *
7  * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
8  * Portions Copyright (C) 1989-1992, Brian Berliner
9  *
10  * You may distribute under the terms of the GNU General Public License as
11  * specified in the README file that comes with the CVS source distribution.
12  *
13  * "import" checks in the vendor release located in the current directory into
14  * the CVS source repository.  The CVS vendor branch support is utilized.
15  *
16  * At least three arguments are expected to follow the options:
17  *	repository	Where the source belongs relative to the CVSROOT
18  *	VendorTag	Vendor's major tag
19  *	VendorReleTag	Tag for this particular release
20  *
21  * Additional arguments specify more Vendor Release Tags.
22  */
23 
24 #include "cvs.h"
25 #include "lstat.h"
26 #include "save-cwd.h"
27 
28 static char *get_comment (const char *user);
29 static int add_rev (char *message, RCSNode *rcs, char *vfile,
30 			  char *vers);
31 static int add_tags (RCSNode *rcs, char *vfile, char *vtag, int targc,
32 		     char *targv[]);
33 static int import_descend (char *message, char *vtag, int targc, char *targv[]);
34 static int import_descend_dir (char *message, char *dir, char *vtag,
35 			       int targc, char *targv[]);
36 static int process_import_file (char *message, char *vfile, char *vtag,
37 				int targc, char *targv[]);
38 static int update_rcs_file (char *message, char *vfile, char *vtag, int targc,
39 			    char *targv[], int inattic);
40 #ifdef PRESERVE_PERMISSIONS_SUPPORT
41 static int preserve_initial_permissions (FILE *fprcs, const char *userfile,
42 					 mode_t file_type, struct stat *sbp);
43 #endif
44 static int expand_and_copy_contents (FILE *fprcs, mode_t file_type,
45 				     const char *user, FILE *fpuser);
46 static void add_log (int ch, char *fname);
47 
48 static int repos_len;
49 static char *vhead;
50 static char *vbranch;
51 static FILE *logfp;
52 static char *repository;
53 static int conflicts;
54 static int use_file_modtime;
55 static char *keyword_opt = NULL;
56 static bool killnew;
57 
58 static const char *const import_usage[] =
59 {
60     "Usage: %s %s [-dX] [-k subst] [-I ign] [-m msg] [-b branch]\n",
61     "    [-W spec] repository vendor-tag release-tags...\n",
62     "\t-d\tUse the file's modification time as the time of import.\n",
63     "\t-X\tWhen importing new files, mark their trunk revisions as dead.\n",
64     "\t-k sub\tSet default RCS keyword substitution mode.\n",
65     "\t-I ign\tMore files to ignore (! to reset).\n",
66     "\t-b bra\tVendor branch id.\n",
67     "\t-m msg\tLog message.\n",
68     "\t-W spec\tWrappers specification line.\n",
69     "(Specify the --help global option for a list of other help options)\n",
70     NULL
71 };
72 
73 int
74 import (int argc, char **argv)
75 {
76     char *message = NULL;
77     char *tmpfile;
78     char *cp;
79     int i, c, msglen, err;
80     List *ulist;
81     Node *p;
82     struct logfile_info *li;
83 
84     if (argc == -1)
85 	usage (import_usage);
86 
87     /* Force -X behaviour or not based on the CVS repository
88        CVSROOT/config setting.  */
89 #ifdef CLIENT_SUPPORT
90     killnew = !current_parsed_root->isremote
91 	      && config->ImportNewFilesToVendorBranchOnly;
92 #else /* !CLIENT_SUPPORT */
93     killnew = config->ImportNewFilesToVendorBranchOnly;
94 #endif /* CLIENT_SUPPORT */
95 
96 
97     ign_setup ();
98     wrap_setup ();
99 
100     vbranch = xstrdup (CVSBRANCH);
101     getoptreset ();
102     while ((c = getopt (argc, argv, "+Qqdb:m:I:k:W:X")) != -1)
103     {
104 	switch (c)
105 	{
106 	    case 'Q':
107 	    case 'q':
108 		/* The CVS 1.5 client sends these options (in addition to
109 		   Global_option requests), so we must ignore them.  */
110 		if (!server_active)
111 		    error (1, 0,
112 			   "-q or -Q must be specified before \"%s\"",
113 			   cvs_cmd_name);
114 		break;
115 	    case 'd':
116 		if (server_active)
117 		{
118 		    /* CVS 1.10 and older clients will send this, but it
119 		       doesn't do any good.  So tell the user we can't
120 		       cope, rather than silently losing.  */
121 		    error (0, 0,
122 			   "warning: not setting the time of import from the file");
123 		    error (0, 0, "due to client limitations");
124 		}
125 		use_file_modtime = 1;
126 		break;
127 	    case 'b':
128 		free (vbranch);
129 		vbranch = xstrdup (optarg);
130 		break;
131 	    case 'm':
132 #ifdef FORCE_USE_EDITOR
133 		use_editor = 1;
134 #else
135 		use_editor = 0;
136 #endif
137 		if (message) free (message);
138 		message = xstrdup (optarg);
139 		break;
140 	    case 'I':
141 		ign_add (optarg, 0);
142 		break;
143             case 'k':
144 		/* RCS_check_kflag returns strings of the form -kxx.  We
145 		   only use it for validation, so we can free the value
146 		   as soon as it is returned. */
147 		free (RCS_check_kflag (optarg));
148 		keyword_opt = optarg;
149 		break;
150 	    case 'W':
151 		wrap_add (optarg, 0);
152 		break;
153 	    case 'X':
154 		killnew = true;
155 		break;
156 	    case '?':
157 	    default:
158 		usage (import_usage);
159 		break;
160 	}
161     }
162     argc -= optind;
163     argv += optind;
164     if (argc < 3)
165 	usage (import_usage);
166 
167     /* This is for handling the Checkin-time request.  It might seem a
168        bit odd to enable the use_file_modtime code even in the case
169        where Checkin-time was not sent for a particular file.  The
170        effect is that we use the time of upload, rather than the time
171        when we call RCS_checkin.  Since those times are both during
172        CVS's run, that seems OK, and it is easier to implement than
173        putting the "was Checkin-time sent" flag in CVS/Entries or some
174        such place.  */
175 
176     if (server_active)
177 	use_file_modtime = 1;
178 
179     /* Don't allow "CVS" as any directory in module path.
180      *
181      * Could abstract this to valid_module_path, but I don't think we'll need
182      * to call it from anywhere else.
183      */
184     if ((cp = strstr (argv[0], "CVS")) &&   /* path contains "CVS" AND ... */
185         ((cp == argv[0]) || ISSLASH (*(cp-1))) && /* /^CVS/ OR m#/CVS# AND ... */
186         ((*(cp+3) == '\0') || ISSLASH (*(cp+3))) /* /CVS$/ OR m#CVS/# */
187        )
188     {
189         error (0, 0,
190                "The word `CVS' is reserved by CVS and may not be used");
191         error (1, 0, "as a directory in a path or as a file name.");
192     }
193 
194     for (i = 1; i < argc; i++)		/* check the tags for validity */
195     {
196 	int j;
197 
198 	RCS_check_tag (argv[i]);
199 	for (j = 1; j < i; j++)
200 	    if (strcmp (argv[j], argv[i]) == 0)
201 		error (1, 0, "tag `%s' was specified more than once", argv[i]);
202     }
203 
204     if (ISABSOLUTE (argv[0]) || pathname_levels (argv[0]) > 0)
205 	/* It is somewhere between a security hole and "unexpected" to
206 	   let the client start mucking around outside the cvsroot
207 	   (wouldn't get the right CVSROOT configuration, &c).  */
208 	error (1, 0, "directory %s not relative within the repository",
209 	       argv[0]);
210 
211     if (current_parsed_root == NULL)
212     {
213 	error (0, 0, "missing CVSROOT environment variable\n");
214 	error (1, 0, "Set it or specify the '-d' option to %s.",
215 	       program_name);
216     }
217     repository = Xasprintf ("%s/%s", current_parsed_root->directory, argv[0]);
218     repos_len = strlen (current_parsed_root->directory);
219 
220     /*
221      * Consistency checks on the specified vendor branch.  It must be
222      * composed of only numbers and dots ('.').  Also, for now we only
223      * support branching to a single level, so the specified vendor branch
224      * must only have two dots in it (like "1.1.1").
225      */
226     {
227 	regex_t pat;
228 	int ret = regcomp (&pat, "^[1-9][0-9]*\\.[1-9][0-9]*\\.[1-9][0-9]*$",
229 			   REG_EXTENDED);
230 	assert (!ret);
231 	if (regexec (&pat, vbranch, 0, NULL, 0))
232 	{
233 	    error (1, 0,
234 "Only numeric branch specifications with two dots are\n"
235 "supported by import, not `%s'.  For example: `1.1.1'.",
236 		   vbranch);
237 	}
238 	regfree (&pat);
239     }
240 
241     /* Set vhead to the branch's parent.  */
242     vhead = xstrdup (vbranch);
243     cp = strrchr (vhead, '.');
244     *cp = '\0';
245 
246 #ifdef CLIENT_SUPPORT
247     if (current_parsed_root->isremote)
248     {
249 	/* For rationale behind calling start_server before do_editor, see
250 	   commit.c  */
251 	start_server ();
252     }
253 #endif
254 
255     if (!server_active && use_editor)
256     {
257 	do_editor (NULL, &message,
258 		   current_parsed_root->isremote ? NULL : repository,
259 		   NULL);
260     }
261     msglen = message == NULL ? 0 : strlen (message);
262     if (msglen == 0 || message[msglen - 1] != '\n')
263     {
264 	char *nm = xmalloc (msglen + 2);
265 	*nm = '\0';
266 	if (message != NULL)
267 	{
268 	    (void) strcpy (nm, message);
269 	    free (message);
270 	}
271 	(void) strcat (nm + msglen, "\n");
272 	message = nm;
273     }
274 
275 #ifdef CLIENT_SUPPORT
276     if (current_parsed_root->isremote)
277     {
278 	int err;
279 
280 	if (vbranch[0] != '\0')
281 	    option_with_arg ("-b", vbranch);
282 	option_with_arg ("-m", message ? message : "");
283 	if (keyword_opt != NULL)
284 	    option_with_arg ("-k", keyword_opt);
285 	if (killnew)
286 	    send_arg ("-X");
287 	/* The only ignore processing which takes place on the server side
288 	   is the CVSROOT/cvsignore file.  But if the user specified -I !,
289 	   the documented behavior is to not process said file.  */
290 	if (ign_inhibit_server)
291 	{
292 	    send_arg ("-I");
293 	    send_arg ("!");
294 	}
295 	wrap_send ();
296 
297 	{
298 	    int i;
299 	    for (i = 0; i < argc; ++i)
300 		send_arg (argv[i]);
301 	}
302 
303 	logfp = stdin;
304 	client_import_setup (repository);
305 	err = import_descend (message, argv[1], argc - 2, argv + 2);
306 	client_import_done ();
307 	if (message)
308 	    free (message);
309 	free (repository);
310 	free (vbranch);
311 	free (vhead);
312 	send_to_server ("import\012", 0);
313 	err += get_responses_and_close ();
314 	return err;
315     }
316 #endif
317 
318     if (!safe_location (NULL))
319     {
320 	error (1, 0, "attempt to import the repository");
321     }
322 
323 /* cvsacl patch */
324 #ifdef SERVER_SUPPORT
325     if (use_cvs_acl /* && server_active */)
326     {
327 	if (!access_allowed (NULL, repository, argv[1], 6, NULL, NULL, 1))
328 	{
329 	    error (stop_at_first_permission_denied, 0,
330 		   "permission denied for %s", Short_Repository (repository));
331 
332 	    return (0);
333 	}
334     }
335 #endif
336 
337     ulist = getlist ();
338     p = getnode ();
339     p->type = UPDATE;
340     p->delproc = update_delproc;
341     p->key = xstrdup ("- Imported sources");
342     li = xmalloc (sizeof (struct logfile_info));
343     li->type = T_TITLE;
344     li->tag = xstrdup (vbranch);
345     li->rev_old = li->rev_new = NULL;
346     p->data = li;
347     (void) addnode (ulist, p);
348     do_verify (&message, repository, ulist);
349 
350     /*
351      * Make all newly created directories writable.  Should really use a more
352      * sophisticated security mechanism here.
353      */
354     (void) umask (cvsumask);
355     make_directories (repository);
356 
357     /* Create the logfile that will be logged upon completion */
358     if ((logfp = cvs_temp_file (&tmpfile)) == NULL)
359 	error (1, errno, "cannot create temporary file `%s'", tmpfile);
360     /* On systems where we can unlink an open file, do so, so it will go
361        away no matter how we exit.  FIXME-maybe: Should be checking for
362        errors but I'm not sure which error(s) we get if we are on a system
363        where one can't unlink open files.  */
364     (void) CVS_UNLINK (tmpfile);
365     (void) fprintf (logfp, "\nVendor Tag:\t%s\n", argv[1]);
366     (void) fprintf (logfp, "Release Tags:\t");
367     for (i = 2; i < argc; i++)
368 	(void) fprintf (logfp, "%s\n\t\t", argv[i]);
369     (void) fprintf (logfp, "\n");
370 
371     /* Just Do It.  */
372     err = import_descend (message, argv[1], argc - 2, argv + 2);
373     if (conflicts || killnew)
374     {
375 	if (!really_quiet)
376 	{
377 	    char buf[20];
378 
379 	    cvs_output_tagged ("+importmergecmd", NULL);
380 	    cvs_output_tagged ("newline", NULL);
381 	    if (conflicts)
382 	        sprintf (buf, "%d", conflicts);
383 	    else
384 	        strcpy (buf, "No");
385 	    cvs_output_tagged ("conflicts", buf);
386 	    cvs_output_tagged ("text", " conflicts created by this import.");
387 	    cvs_output_tagged ("newline", NULL);
388 	    cvs_output_tagged ("text",
389 			       "Use the following command to help the merge:");
390 	    cvs_output_tagged ("newline", NULL);
391 	    cvs_output_tagged ("newline", NULL);
392 	    cvs_output_tagged ("text", "\t");
393 	    cvs_output_tagged ("text", program_name);
394 	    if (CVSroot_cmdline != NULL)
395 	    {
396 		cvs_output_tagged ("text", " -d ");
397 		cvs_output_tagged ("text", CVSroot_cmdline);
398 	    }
399 	    cvs_output_tagged ("text", " checkout -j");
400 	    cvs_output_tagged ("mergetag1", "<prev_rel_tag>");
401 	    cvs_output_tagged ("text", " -j");
402 	    cvs_output_tagged ("mergetag2", argv[2]);
403 	    cvs_output_tagged ("text", " ");
404 	    cvs_output_tagged ("repository", argv[0]);
405 	    cvs_output_tagged ("newline", NULL);
406 	    cvs_output_tagged ("newline", NULL);
407 	    cvs_output_tagged ("-importmergecmd", NULL);
408 	}
409 
410 	/* FIXME: I'm not sure whether we need to put this information
411            into the loginfo.  If we do, then note that it does not
412            report any required -d option.  There is no particularly
413            clean way to tell the server about the -d option used by
414            the client.  */
415 	if (conflicts)
416 	    (void) fprintf (logfp, "\n%d", conflicts);
417 	else
418 	    (void) fprintf (logfp, "\nNo");
419 	(void) fprintf (logfp, " conflicts created by this import.\n");
420 	(void) fprintf (logfp,
421 			"Use the following command to help the merge:\n\n");
422 	(void) fprintf (logfp, "\t%s checkout ", program_name);
423 	(void) fprintf (logfp, "-j%s:yesterday -j%s %s\n\n",
424 			argv[1], argv[1], argv[0]);
425     }
426     else
427     {
428 	if (!really_quiet)
429 	    cvs_output ("\nNo conflicts created by this import\n\n", 0);
430 	(void) fprintf (logfp, "\nNo conflicts created by this import\n\n");
431     }
432 
433     /*
434      * Write out the logfile and clean up.
435      */
436     Update_Logfile (repository, message, logfp, ulist);
437     dellist (&ulist);
438     if (fclose (logfp) < 0)
439 	error (0, errno, "error closing %s", tmpfile);
440 
441     /* Make sure the temporary file goes away, even on systems that don't let
442        you delete a file that's in use.  */
443     if (CVS_UNLINK (tmpfile) < 0 && !existence_error (errno))
444 	error (0, errno, "cannot remove %s", tmpfile);
445     free (tmpfile);
446 
447     if (message)
448 	free (message);
449     free (repository);
450     free (vbranch);
451     free (vhead);
452 
453     return err;
454 }
455 
456 /* Process all the files in ".", then descend into other directories.
457    Returns 0 for success, or >0 on error (in which case a message
458    will have been printed).  */
459 static int
460 import_descend (char *message, char *vtag, int targc, char **targv)
461 {
462     DIR *dirp;
463     struct dirent *dp;
464     int err = 0;
465     List *dirlist = NULL;
466 
467     /* first, load up any per-directory ignore lists */
468     ign_add_file (CVSDOTIGNORE, 1);
469     wrap_add_file (CVSDOTWRAPPER, 1);
470 
471     if (!current_parsed_root->isremote)
472 	lock_dir_for_write (repository);
473 
474     if ((dirp = CVS_OPENDIR (".")) == NULL)
475     {
476 	error (0, errno, "cannot open directory");
477 	err++;
478     }
479     else
480     {
481 	errno = 0;
482 	while ((dp = CVS_READDIR (dirp)) != NULL)
483 	{
484 	    if (strcmp (dp->d_name, ".") == 0 || strcmp (dp->d_name, "..") == 0)
485 		goto one_more_time_boys;
486 
487 	    /* CVS directories are created in the temp directory by
488 	       server.c because it doesn't special-case import.  So
489 	       don't print a message about them, regardless of -I!.  */
490 	    if (server_active && strcmp (dp->d_name, CVSADM) == 0)
491 		goto one_more_time_boys;
492 
493 	    if (ign_name (dp->d_name))
494 	    {
495 		add_log ('I', dp->d_name);
496 		goto one_more_time_boys;
497 	    }
498 
499 	    if (
500 #ifdef DT_DIR
501 		(dp->d_type == DT_DIR
502 		 || (dp->d_type == DT_UNKNOWN && isdir (dp->d_name)))
503 #else
504 		isdir (dp->d_name)
505 #endif
506 		&& !wrap_name_has (dp->d_name, WRAP_TOCVS)
507 		)
508 	    {
509 		Node *n;
510 
511 		if (dirlist == NULL)
512 		    dirlist = getlist ();
513 
514 		n = getnode ();
515 		n->key = xstrdup (dp->d_name);
516 		addnode (dirlist, n);
517 	    }
518 	    else if (
519 #ifdef DT_DIR
520 		     dp->d_type == DT_LNK
521 		     || (dp->d_type == DT_UNKNOWN && islink (dp->d_name))
522 #else
523 		     islink (dp->d_name)
524 #endif
525 		     )
526 	    {
527 		add_log ('L', dp->d_name);
528 		err++;
529 	    }
530 	    else
531 	    {
532 #ifdef CLIENT_SUPPORT
533 		if (current_parsed_root->isremote)
534 		    err += client_process_import_file (message, dp->d_name,
535                                                        vtag, targc, targv,
536                                                        repository,
537                                                        keyword_opt != NULL &&
538 						       keyword_opt[0] == 'b',
539 						       use_file_modtime);
540 		else
541 #endif
542 		    err += process_import_file (message, dp->d_name,
543 						vtag, targc, targv);
544 	    }
545 	one_more_time_boys:
546 	    errno = 0;
547 	}
548 	if (errno != 0)
549 	{
550 	    error (0, errno, "cannot read directory");
551 	    ++err;
552 	}
553 	(void) CVS_CLOSEDIR (dirp);
554     }
555 
556     if (!current_parsed_root->isremote)
557 	Simple_Lock_Cleanup ();
558 
559     if (dirlist != NULL)
560     {
561 	Node *head, *p;
562 
563 	head = dirlist->list;
564 	for (p = head->next; p != head; p = p->next)
565 	{
566 	    err += import_descend_dir (message, p->key, vtag, targc, targv);
567 	}
568 
569 	dellist (&dirlist);
570     }
571 
572     return err;
573 }
574 
575 /*
576  * Process the argument import file.
577  */
578 static int
579 process_import_file (char *message, char *vfile, char *vtag, int targc,
580 		     char **targv)
581 {
582     char *rcs;
583     int inattic = 0;
584 
585     rcs = Xasprintf ("%s/%s%s", repository, vfile, RCSEXT);
586     if (!isfile (rcs))
587     {
588 	char *attic_name;
589 
590 	attic_name = xmalloc (strlen (repository) + strlen (vfile) +
591 			      sizeof (CVSATTIC) + sizeof (RCSEXT) + 10);
592 	(void) sprintf (attic_name, "%s/%s/%s%s", repository, CVSATTIC,
593 			vfile, RCSEXT);
594 	if (!isfile (attic_name))
595 	{
596 	    int retval;
597 	    char *free_opt = NULL;
598 	    char *our_opt = keyword_opt;
599 
600 	    /* If marking newly-imported files as dead, they must be
601 	       created in the attic!  */
602 	    if (!killnew)
603 	        free (attic_name);
604 	    else
605 	    {
606 		free (rcs);
607 		rcs = attic_name;
608 
609 		/* Attempt to make the Attic directory, in case it
610 		   does not exist.  */
611 		(void) sprintf (rcs, "%s/%s", repository, CVSATTIC);
612 		if (noexec == 0 && CVS_MKDIR (rcs, 0777 ) != 0 && errno != EEXIST)
613 		    error (1, errno, "cannot make directory `%s'", rcs);
614 
615 		/* Note that the above clobbered the path name, so we
616 		   recreate it here.  */
617 		(void) sprintf (rcs, "%s/%s/%s%s", repository, CVSATTIC,
618 				vfile, RCSEXT);
619 	    }
620 
621 	    /*
622 	     * A new import source file; it doesn't exist as a ,v within the
623 	     * repository nor in the Attic -- create it anew.
624 	     */
625 	    add_log ('N', vfile);
626 
627 #ifdef SERVER_SUPPORT
628 	    /* The most reliable information on whether the file is binary
629 	       is what the client told us.  That is because if the client had
630 	       the wrong idea about binaryness, it corrupted the file, so
631 	       we might as well believe the client.  */
632 	    if (server_active)
633 	    {
634 		Node *node;
635 		List *entries;
636 
637 		/* Reading all the entries for each file is fairly silly, and
638 		   probably slow.  But I am too lazy at the moment to do
639 		   anything else.  */
640 		entries = Entries_Open (0, NULL);
641 		node = findnode_fn (entries, vfile);
642 		if (node != NULL)
643 		{
644 		    Entnode *entdata = node->data;
645 
646 		    if (entdata->type == ENT_FILE)
647 		    {
648 			assert (entdata->options[0] == '-'
649 				&& entdata->options[1] == 'k');
650 			our_opt = xstrdup (entdata->options + 2);
651 			free_opt = our_opt;
652 		    }
653 		}
654 		Entries_Close (entries);
655 	    }
656 #endif
657 
658 	    retval = add_rcs_file (message, rcs, vfile, vhead, our_opt,
659 				   vbranch, vtag, targc, targv,
660 				   NULL, 0, logfp, killnew);
661 	    if (free_opt != NULL)
662 		free (free_opt);
663 	    free (rcs);
664 	    return retval;
665 	}
666 	free (attic_name);
667 	inattic = 1;
668     }
669 
670     free (rcs);
671     /*
672      * an rcs file exists. have to do things the official, slow, way.
673      */
674     return update_rcs_file (message, vfile, vtag, targc, targv, inattic);
675 }
676 
677 /*
678  * The RCS file exists; update it by adding the new import file to the
679  * (possibly already existing) vendor branch.
680  */
681 static int
682 update_rcs_file (char *message, char *vfile, char *vtag, int targc,
683 		 char **targv, int inattic)
684 {
685     Vers_TS *vers;
686     int letter;
687     char *tocvsPath;
688     char *expand;
689     struct file_info finfo;
690 
691     memset (&finfo, 0, sizeof finfo);
692     finfo.file = vfile;
693     /* Not used, so don't worry about it.  */
694     finfo.update_dir = NULL;
695     finfo.fullname = finfo.file;
696     finfo.repository = repository;
697     finfo.entries = NULL;
698     finfo.rcs = NULL;
699     vers = Version_TS (&finfo, NULL, vbranch, NULL, 1, 0);
700     if (vers->vn_rcs != NULL
701 	&& !RCS_isdead (vers->srcfile, vers->vn_rcs))
702     {
703 	int different;
704 
705 	/*
706 	 * The rcs file does have a revision on the vendor branch. Compare
707 	 * this revision with the import file; if they match exactly, there
708 	 * is no need to install the new import file as a new revision to the
709 	 * branch.  Just tag the revision with the new import tags.
710 	 *
711 	 * This is to try to cut down the number of "C" conflict messages for
712 	 * locally modified import source files.
713 	 */
714 	tocvsPath = wrap_tocvs_process_file (vfile);
715 	/* FIXME: Why don't we pass tocvsPath to RCS_cmp_file if it is
716            not NULL?  */
717 	expand = (vers->srcfile->expand != NULL
718 		  && vers->srcfile->expand[0] == 'b') ? "-kb" : "-ko";
719 	different = RCS_cmp_file (vers->srcfile, vers->vn_rcs, NULL,
720 	                          NULL, expand, vfile);
721 	if (tocvsPath)
722 	    if (unlink_file_dir (tocvsPath) < 0)
723 		error (0, errno, "cannot remove %s", tocvsPath);
724 
725 	if (!different)
726 	{
727 	    int retval = 0;
728 
729 	    /*
730 	     * The two files are identical.  Just update the tags, print the
731 	     * "U", signifying that the file has changed, but needs no
732 	     * attention, and we're done.
733 	     */
734 	    if (add_tags (vers->srcfile, vfile, vtag, targc, targv))
735 		retval = 1;
736 	    add_log ('U', vfile);
737 	    freevers_ts (&vers);
738 	    return retval;
739 	}
740     }
741 
742     /* We may have failed to parse the RCS file; check just in case */
743     if (vers->srcfile == NULL ||
744 	add_rev (message, vers->srcfile, vfile, vers->vn_rcs) ||
745 	add_tags (vers->srcfile, vfile, vtag, targc, targv))
746     {
747 	freevers_ts (&vers);
748 	return 1;
749     }
750 
751     if (vers->srcfile->branch == NULL || inattic ||
752 	strcmp (vers->srcfile->branch, vbranch) != 0)
753     {
754 	conflicts++;
755 	letter = 'C';
756     }
757     else
758 	letter = 'U';
759     add_log (letter, vfile);
760 
761     freevers_ts (&vers);
762     return 0;
763 }
764 
765 /*
766  * Add the revision to the vendor branch
767  */
768 static int
769 add_rev (char *message, RCSNode *rcs, char *vfile, char *vers)
770 {
771     int locked, status, ierrno;
772     char *tocvsPath;
773 
774     if (noexec)
775 	return 0;
776 
777     locked = 0;
778     if (vers != NULL)
779     {
780 	/* Before RCS_lock existed, we were directing stdout, as well as
781 	   stderr, from the RCS command, to DEVNULL.  I wouldn't guess that
782 	   was necessary, but I don't know for sure.  */
783 	/* Earlier versions of this function printed a `fork failed' error
784 	   when RCS_lock returned an error code.  That's not appropriate
785 	   now that RCS_lock is librarified, but should the error text be
786 	   preserved? */
787 	if (RCS_lock (rcs, vbranch, 1) != 0)
788 	    return 1;
789 	locked = 1;
790 	RCS_rewrite (rcs, NULL, NULL);
791     }
792     tocvsPath = wrap_tocvs_process_file (vfile);
793 
794     status = RCS_checkin (rcs, NULL, tocvsPath == NULL ? vfile : tocvsPath,
795 			  message, vbranch, 0,
796 			  (RCS_FLAGS_QUIET | RCS_FLAGS_KEEPFILE
797 			   | (use_file_modtime ? RCS_FLAGS_MODTIME : 0)));
798     ierrno = errno;
799 
800     if ((tocvsPath != NULL) && (unlink_file_dir (tocvsPath) < 0))
801 	error (0, errno, "cannot remove %s", tocvsPath);
802 
803     if (status)
804     {
805 	if (!noexec)
806 	{
807 	    fperrmsg (logfp, 0, status == -1 ? ierrno : 0,
808 		      "ERROR: Check-in of %s failed", rcs->path);
809 	    error (0, status == -1 ? ierrno : 0,
810 		   "ERROR: Check-in of %s failed", rcs->path);
811 	}
812 	if (locked)
813 	{
814 	    (void) RCS_unlock (rcs, vbranch, 0);
815 	    RCS_rewrite (rcs, NULL, NULL);
816 	}
817 	return 1;
818     }
819     return 0;
820 }
821 
822 /*
823  * Add the vendor branch tag and all the specified import release tags to the
824  * RCS file.  The vendor branch tag goes on the branch root (1.1.1) while the
825  * vendor release tags go on the newly added leaf of the branch (1.1.1.1,
826  * 1.1.1.2, ...).
827  */
828 static int
829 add_tags (RCSNode *rcs, char *vfile, char *vtag, int targc, char **targv)
830 {
831     int i, ierrno;
832     Vers_TS *vers;
833     int retcode = 0;
834     struct file_info finfo;
835 
836     if (noexec)
837 	return 0;
838 
839     if ((retcode = RCS_settag (rcs, vtag, vbranch)) != 0)
840     {
841 	ierrno = errno;
842 	fperrmsg (logfp, 0, retcode == -1 ? ierrno : 0,
843 		  "ERROR: Failed to set tag %s in %s", vtag, rcs->path);
844 	error (0, retcode == -1 ? ierrno : 0,
845 	       "ERROR: Failed to set tag %s in %s", vtag, rcs->path);
846 	return 1;
847     }
848     RCS_rewrite (rcs, NULL, NULL);
849 
850     memset (&finfo, 0, sizeof finfo);
851     finfo.file = vfile;
852     /* Not used, so don't worry about it.  */
853     finfo.update_dir = NULL;
854     finfo.fullname = finfo.file;
855     finfo.repository = repository;
856     finfo.entries = NULL;
857     finfo.rcs = NULL;
858     vers = Version_TS (&finfo, NULL, vtag, NULL, 1, 0);
859     for (i = 0; i < targc; i++)
860     {
861 	if ((retcode = RCS_settag (rcs, targv[i], vers->vn_rcs)) == 0)
862 	    RCS_rewrite (rcs, NULL, NULL);
863 	else
864 	{
865 	    ierrno = errno;
866 	    fperrmsg (logfp, 0, retcode == -1 ? ierrno : 0,
867 		      "WARNING: Couldn't add tag %s to %s", targv[i],
868 		      rcs->path);
869 	    error (0, retcode == -1 ? ierrno : 0,
870 		   "WARNING: Couldn't add tag %s to %s", targv[i],
871 		   rcs->path);
872 	}
873     }
874     freevers_ts (&vers);
875     return 0;
876 }
877 
878 /*
879  * Stolen from rcs/src/rcsfnms.c, and adapted/extended.
880  */
881 struct compair
882 {
883     char *suffix, *comlead;
884 };
885 
886 static const struct compair comtable[] =
887 {
888 
889 /*
890  * comtable pairs each filename suffix with a comment leader. The comment
891  * leader is placed before each line generated by the $Log keyword. This
892  * table is used to guess the proper comment leader from the working file's
893  * suffix during initial ci (see InitAdmin()). Comment leaders are needed for
894  * languages without multiline comments; for others they are optional.
895  *
896  * I believe that the comment leader is unused if you are using RCS 5.7, which
897  * decides what leader to use based on the text surrounding the $Log keyword
898  * rather than a specified comment leader.
899  */
900     {"a", "-- "},			/* Ada		 */
901     {"ada", "-- "},
902     {"adb", "-- "},
903     {"asm", ";; "},			/* assembler (MS-DOS) */
904     {"ads", "-- "},			/* Ada		 */
905     {"bas", "' "},    			/* Visual Basic code */
906     {"bat", ":: "},			/* batch (MS-DOS) */
907     {"body", "-- "},			/* Ada		 */
908     {"c", " * "},			/* C		 */
909     {"c++", "// "},			/* C++ in all its infinite guises */
910     {"cc", "// "},
911     {"cpp", "// "},
912     {"cxx", "// "},
913     {"m", "// "},			/* Objective-C */
914     {"cl", ";;; "},			/* Common Lisp	 */
915     {"cmd", ":: "},			/* command (OS/2) */
916     {"cmf", "c "},			/* CM Fortran	 */
917     {"cs", " * "},			/* C*		 */
918     {"csh", "# "},			/* shell	 */
919     {"dlg", " * "},   			/* MS Windows dialog file */
920     {"e", "# "},			/* efl		 */
921     {"epsf", "% "},			/* encapsulated postscript */
922     {"epsi", "% "},			/* encapsulated postscript */
923     {"el", "; "},			/* Emacs Lisp	 */
924     {"f", "c "},			/* Fortran	 */
925     {"for", "c "},
926     {"frm", "' "},    			/* Visual Basic form */
927     {"h", " * "},			/* C-header	 */
928     {"hh", "// "},			/* C++ header	 */
929     {"hpp", "// "},
930     {"hxx", "// "},
931     {"in", "# "},			/* for Makefile.in */
932     {"l", " * "},			/* lex (conflict between lex and
933 					 * franzlisp) */
934     {"mac", ";; "},			/* macro (DEC-10, MS-DOS, PDP-11,
935 					 * VMS, etc) */
936     {"mak", "# "},    			/* makefile, e.g. Visual C++ */
937     {"me", ".\\\" "},			/* me-macros	t/nroff	 */
938     {"ml", "; "},			/* mocklisp	 */
939     {"mm", ".\\\" "},			/* mm-macros	t/nroff	 */
940     {"ms", ".\\\" "},			/* ms-macros	t/nroff	 */
941     {"man", ".\\\" "},			/* man-macros	t/nroff	 */
942     {"1", ".\\\" "},			/* feeble attempt at man pages... */
943     {"2", ".\\\" "},
944     {"3", ".\\\" "},
945     {"4", ".\\\" "},
946     {"5", ".\\\" "},
947     {"6", ".\\\" "},
948     {"7", ".\\\" "},
949     {"8", ".\\\" "},
950     {"9", ".\\\" "},
951     {"p", " * "},			/* pascal	 */
952     {"pas", " * "},
953     {"pl", "# "},			/* perl	(conflict with Prolog) */
954     {"ps", "% "},			/* postscript	 */
955     {"psw", "% "},			/* postscript wrap */
956     {"pswm", "% "},			/* postscript wrap */
957     {"r", "# "},			/* ratfor	 */
958     {"rc", " * "},			/* Microsoft Windows resource file */
959     {"red", "% "},			/* psl/rlisp	 */
960 #ifdef sparc
961     {"s", "! "},			/* assembler	 */
962 #endif
963 #ifdef mc68000
964     {"s", "| "},			/* assembler	 */
965 #endif
966 #ifdef pdp11
967     {"s", "/ "},			/* assembler	 */
968 #endif
969 #ifdef vax
970     {"s", "# "},			/* assembler	 */
971 #endif
972 #ifdef __ksr__
973     {"s", "# "},			/* assembler	 */
974     {"S", "# "},			/* Macro assembler */
975 #endif
976     {"sh", "# "},			/* shell	 */
977     {"sl", "% "},			/* psl		 */
978     {"spec", "-- "},			/* Ada		 */
979     {"tex", "% "},			/* tex		 */
980     {"y", " * "},			/* yacc		 */
981     {"ye", " * "},			/* yacc-efl	 */
982     {"yr", " * "},			/* yacc-ratfor	 */
983     {"", "# "},				/* default for empty suffix	 */
984     {NULL, "# "}			/* default for unknown suffix;	 */
985 /* must always be last		 */
986 };
987 
988 
989 
990 static char *
991 get_comment (const char *user)
992 {
993     char *cp, *suffix;
994     char *suffix_path;
995     int i;
996     char *retval;
997 
998     suffix_path = xmalloc (strlen (user) + 5);
999     cp = strrchr (user, '.');
1000     if (cp != NULL)
1001     {
1002 	cp++;
1003 
1004 	/*
1005 	 * Convert to lower-case, since we are not concerned about the
1006 	 * case-ness of the suffix.
1007 	 */
1008 	(void) strcpy (suffix_path, cp);
1009 	for (cp = suffix_path; *cp; cp++)
1010 	    if (isupper ((unsigned char) *cp))
1011 		*cp = tolower (*cp);
1012 	suffix = suffix_path;
1013     }
1014     else
1015 	suffix = "";			/* will use the default */
1016     for (i = 0;; i++)
1017     {
1018 	if (comtable[i].suffix == NULL)
1019 	{
1020 	    /* Default.  Note we'll always hit this case before we
1021 	       ever return NULL.  */
1022 	    retval = comtable[i].comlead;
1023 	    break;
1024 	}
1025 	if (strcmp (suffix, comtable[i].suffix) == 0)
1026 	{
1027 	    retval = comtable[i].comlead;
1028 	    break;
1029 	}
1030     }
1031     free (suffix_path);
1032     return retval;
1033 }
1034 
1035 /* Create a new RCS file from scratch.
1036  *
1037  * This probably should be moved to rcs.c now that it is called from
1038  * places outside import.c.
1039  *
1040  * INPUTS
1041  *   message    Log message for the addition.  Not used if add_vhead == NULL.
1042  *   rcs        Filename of the RCS file to create.  Note that if 'do_killnew'
1043  *		is set, this file should be in the Attic directory, and the
1044  *		Attic directory must already exist.
1045  *   user       Filename of the file to serve as the contents of the initial
1046  *              revision.  Even if add_vhead is NULL, we use this to determine
1047  *              the modes to give the new RCS file.
1048  *   add_vhead  Revision number of head that we are adding.  Normally 1.1 but
1049  *              could be another revision as long as ADD_VBRANCH is a branch
1050  *              from it.  If NULL, then just add an empty file without any
1051  *              revisions (similar to the one created by "rcs -i").
1052  *   key_opt    Keyword expansion mode, e.g., "b" for binary.  NULL means the
1053  *              default behavior.
1054  *   add_vbranch
1055  *              Vendor branch to import to, or NULL if none.  If non-NULL, then
1056  *              vtag should also be non-NULL.
1057  *   vtag
1058  *   targc      Number of elements in TARGV.
1059  *   targv      The list of tags to attached to this imported revision.
1060  *   desctext   If non-NULL, description for the file.  If NULL, the
1061  *              description will be empty.
1062  *   desclen    The number of bytes in desctext.
1063  *   add_logfp  Write errors to here as well as via error (), or NULL if we
1064  *              should use only error ().
1065  *   do_killnew	Mark newly-imported files as being dead on the trunk, i.e.,
1066  *		as being imported only to the vendor branch.
1067  *
1068  * RETURNS
1069  *   Return value is 0 for success, or nonzero for failure (in which
1070  *   case an error message will have already been printed).
1071  */
1072 int
1073 add_rcs_file (const char *message, const char *rcs, const char *user,
1074               const char *add_vhead, const char *key_opt,
1075               const char *add_vbranch, const char *vtag, int targc,
1076               char **targv, const char *desctext, size_t desclen,
1077               FILE *add_logfp, bool do_killnew)
1078 {
1079     FILE *fprcs, *fpuser;
1080     struct stat sb;
1081     struct tm *ftm;
1082     time_t now;
1083     char altdate1[MAXDATELEN];
1084     char *author;
1085     int i, ierrno, err = 0;
1086     mode_t mode;
1087     char *tocvsPath;
1088     const char *userfile;
1089     char *free_opt = NULL;
1090     mode_t file_type;
1091     char *dead_revision = NULL;
1092 
1093     if (noexec)
1094 	return 0;
1095 
1096     if (do_killnew)
1097     {
1098 	char *last_place;
1099 	int last_number;
1100 
1101 	/* If we are marking the newly imported file as dead, we must
1102 	   have a head revision.  */
1103 	if (add_vhead == NULL)
1104 	    error (1, 0, "killing new file attempted when no head revision is being added");
1105 
1106 	/* One extra byte for NUL, plus one for carry generated by adding
1107 	   one to the last number in the add_vhead revision.  */
1108 	dead_revision = xmalloc (strlen (add_vhead) + 2);
1109 	strcpy (dead_revision, add_vhead);
1110 
1111 	/* Find the loacation of the last number, which we will increment
1112 	   and overwrite.  Note that this handles single numbers (w/o
1113 	   dots), which is probably unnecessary.  */
1114 	if ((last_place = strrchr (dead_revision, '.')) != NULL)
1115 	    last_place++;
1116 	else
1117 	    last_place = dead_revision;
1118 	last_number = atoi (last_place);
1119 	if (++last_number <= 0)
1120 	  error (1, 0, "invalid revision number %s", add_vhead);
1121 	sprintf (last_place, "%d", last_number);
1122     }
1123 
1124     /* Note that as the code stands now, the -k option overrides any
1125        settings in wrappers (whether CVSROOT/cvswrappers, -W, or
1126        whatever).  Some have suggested this should be the other way
1127        around.  As far as I know the documentation doesn't say one way
1128        or the other.  Before making a change of this sort, should think
1129        about what is best, document it (in cvs.texinfo and NEWS), &c.  */
1130 
1131     if (key_opt == NULL)
1132     {
1133 	if (wrap_name_has (user, WRAP_RCSOPTION))
1134 	{
1135 	    key_opt = free_opt = wrap_rcsoption (user, 0);
1136 	}
1137     }
1138 
1139     tocvsPath = wrap_tocvs_process_file (user);
1140     userfile = (tocvsPath == NULL ? user : tocvsPath);
1141 
1142     /* Opening in text mode is probably never the right thing for the
1143        server (because the protocol encodes text files in a fashion
1144        which does not depend on what the client or server OS is, as
1145        documented in cvsclient.texi), but as long as the server just
1146        runs on unix it is a moot point.  */
1147 
1148     /* If PreservePermissions is set, then make sure that the file
1149        is a plain file before trying to open it.  Longstanding (although
1150        often unpopular) CVS behavior has been to follow symlinks, so we
1151        maintain that behavior if PreservePermissions is not on.
1152 
1153        NOTE: this error message used to be `cannot fstat', but is now
1154        `cannot lstat'.  I don't see a way around this, since we must
1155        stat the file before opening it. -twp */
1156 
1157     if (lstat (userfile, &sb) < 0)
1158     {
1159 	/* not fatal, continue import */
1160 	if (add_logfp != NULL)
1161 	    fperrmsg (add_logfp, 0, errno,
1162 			  "ERROR: cannot lstat file %s", userfile);
1163 	error (0, errno, "cannot lstat file %s", userfile);
1164 	goto read_error;
1165     }
1166     file_type = sb.st_mode & S_IFMT;
1167 
1168     fpuser = NULL;
1169     if (
1170 #ifdef PRESERVE_PERMISSIONS_SUPPORT
1171 	!config->preserve_perms ||
1172 #endif /* PRESERVE_PERMISSIONS_SUPPORT */
1173 	file_type == S_IFREG)
1174     {
1175 	fpuser = CVS_FOPEN (userfile,
1176 			    ((key_opt != NULL && strcmp (key_opt, "b") == 0)
1177 			     ? "rb"
1178 			     : "r")
1179 	    );
1180 	if (fpuser == NULL)
1181 	{
1182 	    /* not fatal, continue import */
1183 	    if (add_logfp != NULL)
1184 		fperrmsg (add_logfp, 0, errno,
1185 			  "ERROR: cannot read file %s", userfile);
1186 	    error (0, errno, "ERROR: cannot read file %s", userfile);
1187 	    goto read_error;
1188 	}
1189     }
1190 
1191     fprcs = CVS_FOPEN (rcs, "w+b");
1192     if (fprcs == NULL)
1193     {
1194 	ierrno = errno;
1195 	goto write_error_noclose;
1196     }
1197 
1198     /*
1199      * putadmin()
1200      */
1201     if (add_vhead != NULL)
1202     {
1203 	if (fprintf (fprcs, "head     %s;\012",
1204 	             do_killnew ? dead_revision : add_vhead) < 0)
1205 	    goto write_error;
1206     }
1207     else
1208     {
1209 	if (fprintf (fprcs, "head     ;\012") < 0)
1210 	    goto write_error;
1211     }
1212 
1213     /* This sets the default branch.  If using the 'do_killnew' functionality,
1214        where imports don't show up until merged, no default branch should
1215        be set.  */
1216     if (add_vbranch != NULL && ! do_killnew)
1217     {
1218 	if (fprintf (fprcs, "branch   %s;\012", add_vbranch) < 0)
1219 	    goto write_error;
1220     }
1221     if (fprintf (fprcs, "access   ;\012") < 0 ||
1222 	fprintf (fprcs, "symbols  ") < 0)
1223     {
1224 	goto write_error;
1225     }
1226 
1227     for (i = targc - 1; i >= 0; i--)
1228     {
1229 	/* RCS writes the symbols backwards */
1230 	assert (add_vbranch != NULL);
1231 	if (fprintf (fprcs, "%s:%s.1 ", targv[i], add_vbranch) < 0)
1232 	    goto write_error;
1233     }
1234 
1235     if (add_vbranch != NULL)
1236     {
1237 	if (fprintf (fprcs, "%s:%s", vtag, add_vbranch) < 0)
1238 	    goto write_error;
1239     }
1240     if (fprintf (fprcs, ";\012") < 0)
1241 	goto write_error;
1242 
1243     if (fprintf (fprcs, "locks    ; strict;\012") < 0 ||
1244 	/* XXX - make sure @@ processing works in the RCS file */
1245 	fprintf (fprcs, "comment  @%s@;\012", get_comment (user)) < 0)
1246     {
1247 	goto write_error;
1248     }
1249 
1250     if (key_opt != NULL && strcmp (key_opt, "kv") != 0)
1251     {
1252 	if (fprintf (fprcs, "expand   @%s@;\012", key_opt) < 0)
1253 	{
1254 	    goto write_error;
1255 	}
1256     }
1257 
1258     if (fprintf (fprcs, "\012") < 0)
1259       goto write_error;
1260 
1261     /* Write the revision(s), with the date and author and so on
1262        (that is "delta" rather than "deltatext" from rcsfile(5)).  */
1263 
1264     if (use_file_modtime)
1265 	now = sb.st_mtime;
1266     else
1267 	(void) time (&now);
1268     ftm = gmtime (&now);
1269     (void) sprintf (altdate1, DATEFORM,
1270 		    ftm->tm_year + (ftm->tm_year < 100 ? 0 : 1900),
1271 		    ftm->tm_mon + 1, ftm->tm_mday, ftm->tm_hour,
1272 		    ftm->tm_min, ftm->tm_sec);
1273     author = getcaller ();
1274 
1275     if (do_killnew)
1276     {
1277 	if (fprintf (fprcs, "\012%s\012", dead_revision) < 0 ||
1278 	fprintf (fprcs, "date     %s;  author %s;  state %s;\012",
1279 		 altdate1, author, RCSDEAD) < 0)
1280 	goto write_error;
1281 
1282 	if (fprintf (fprcs, "branches;\012") < 0)
1283 	    goto write_error;
1284 	if (fprintf (fprcs, "next    %s;\012", add_vhead) < 0)
1285 	    goto write_error;
1286 
1287 	if (fprintf (fprcs, "commitid        %s;\012", global_session_id) < 0)
1288 	    goto write_error;
1289 
1290 #ifdef PRESERVE_PERMISSIONS_SUPPORT
1291 	/* Store initial permissions if necessary. */
1292 	if (config->preserve_perms)
1293 	{
1294 	    if (preserve_initial_permissions (fprcs, userfile,
1295 					      file_type, sbp))
1296 		goto write_error;
1297 	}
1298 #endif
1299     }
1300 
1301     if (add_vhead != NULL)
1302     {
1303 	if (fprintf (fprcs, "\012%s\012", add_vhead) < 0 ||
1304 	fprintf (fprcs, "date     %s;  author %s;  state Exp;\012",
1305 		 altdate1, author) < 0)
1306 	goto write_error;
1307 
1308 	if (fprintf (fprcs, "branches") < 0)
1309 	    goto write_error;
1310 	if (add_vbranch != NULL)
1311 	{
1312 	    if (fprintf (fprcs, " %s.1", add_vbranch) < 0)
1313 		goto write_error;
1314 	}
1315 	if (fprintf (fprcs, ";\012") < 0)
1316 	    goto write_error;
1317 
1318 	if (fprintf (fprcs, "next     ;\012") < 0)
1319 	    goto write_error;
1320 
1321 	if (fprintf (fprcs, "commitid        %s;\012", global_session_id) < 0)
1322 	    goto write_error;
1323 
1324 #ifdef PRESERVE_PERMISSIONS_SUPPORT
1325 	/* Store initial permissions if necessary. */
1326 	if (config->preserve_perms)
1327 	{
1328 	    if (preserve_initial_permissions (fprcs, userfile,
1329 					      file_type, sbp))
1330 		goto write_error;
1331 	}
1332 #endif
1333 
1334 	if (add_vbranch != NULL)
1335 	{
1336 	    if (fprintf (fprcs, "\012%s.1\012", add_vbranch) < 0 ||
1337 		fprintf (fprcs, "date     %s;  author %s;  state Exp;\012",
1338 			 altdate1, author) < 0 ||
1339 		fprintf (fprcs, "branches ;\012") < 0 ||
1340 		fprintf (fprcs, "next     ;\012") < 0 ||
1341 	        fprintf (fprcs, "commitid        %s;\012", global_session_id) < 0)
1342 		goto write_error;
1343 
1344 #ifdef PRESERVE_PERMISSIONS_SUPPORT
1345 	    /* Store initial permissions if necessary. */
1346 	    if (config->preserve_perms)
1347 	    {
1348 		if (preserve_initial_permissions (fprcs, userfile,
1349 						  file_type, sbp))
1350 		    goto write_error;
1351 	    }
1352 #endif
1353 
1354 	    if (fprintf (fprcs, "\012") < 0)
1355 		goto write_error;
1356 	}
1357     }
1358 
1359     /* Now write the description (possibly empty).  */
1360     if (fprintf (fprcs, "\012desc\012") < 0 ||
1361 	fprintf (fprcs, "@") < 0)
1362 	goto write_error;
1363     if (desctext != NULL)
1364     {
1365 	/* The use of off_t not size_t for the second argument is very
1366 	   strange, since we are dealing with something which definitely
1367 	   fits in memory.  */
1368 	if (expand_at_signs (desctext, (off_t) desclen, fprcs) < 0)
1369 	    goto write_error;
1370     }
1371     if (fprintf (fprcs, "@\012\012\012") < 0)
1372 	goto write_error;
1373 
1374     /* Now write the log messages and contents for the revision(s) (that
1375        is, "deltatext" rather than "delta" from rcsfile(5)).  */
1376 
1377     if (do_killnew)
1378     {
1379 	if (fprintf (fprcs, "\012%s\012", dead_revision) < 0 ||
1380 	    fprintf (fprcs, "log\012@") < 0)
1381 	    goto write_error;
1382 	if (fprintf (fprcs, "Revision %s was added on the vendor branch.\012",
1383 		     add_vhead) < 0)
1384 	    goto write_error;
1385 	if (fprintf (fprcs, "@\012") < 0 ||
1386 	    fprintf (fprcs, "text\012@") < 0)
1387 	{
1388 	    goto write_error;
1389 	}
1390 
1391 	/* Now copy over the contents of the file, expanding at signs.  */
1392 	if (expand_and_copy_contents (fprcs, file_type, user, fpuser))
1393 	    goto write_error;
1394 
1395 	if (fprintf (fprcs, "@\012\012") < 0)
1396 	    goto write_error;
1397     }
1398 
1399     if (add_vhead != NULL)
1400     {
1401 	if (fprintf (fprcs, "\012%s\012", add_vhead) < 0 ||
1402 	    fprintf (fprcs, "log\012@") < 0)
1403 	    goto write_error;
1404 	if (add_vbranch != NULL)
1405 	{
1406 	    /* We are going to put the log message in the revision on the
1407 	       branch.  So putting it here too seems kind of redundant, I
1408 	       guess (and that is what CVS has always done, anyway).  */
1409 	    if (fprintf (fprcs, "Initial revision\012") < 0)
1410 		goto write_error;
1411 	}
1412 	else
1413 	{
1414 	    if (expand_at_signs (message, (off_t) strlen (message), fprcs) < 0)
1415 		goto write_error;
1416 	}
1417 	if (fprintf (fprcs, "@\012") < 0 ||
1418 	    fprintf (fprcs, "text\012@") < 0)
1419 	{
1420 	    goto write_error;
1421 	}
1422 
1423 	/* Now copy over the contents of the file, expanding at signs.
1424 	 * If config->preserve_perms is set, do this only for regular files.
1425 	 */
1426 	if (!do_killnew)
1427 	{
1428             /* Now copy over the contents of the file, expanding at signs,
1429 	       if not done as part of do_killnew handling above.  */
1430 	    if (expand_and_copy_contents (fprcs, file_type, user, fpuser))
1431 	        goto write_error;
1432 	}
1433 
1434 	if (fprintf (fprcs, "@\012\012") < 0)
1435 	    goto write_error;
1436 
1437 	if (add_vbranch != NULL)
1438 	{
1439 	    if (fprintf (fprcs, "\012%s.1\012", add_vbranch) < 0 ||
1440 		fprintf (fprcs, "log\012@") < 0 ||
1441 		expand_at_signs (message,
1442 				 (off_t) strlen (message), fprcs) < 0 ||
1443 		fprintf (fprcs, "@\012text\012") < 0 ||
1444 		fprintf (fprcs, "@@\012") < 0)
1445 		goto write_error;
1446 	}
1447     }
1448 
1449     if (fclose (fprcs) == EOF)
1450     {
1451 	ierrno = errno;
1452 	goto write_error_noclose;
1453     }
1454     /* Close fpuser only if we opened it to begin with. */
1455     if (fpuser != NULL)
1456     {
1457 	if (fclose (fpuser) < 0)
1458 	    error (0, errno, "cannot close %s", user);
1459     }
1460 
1461     /*
1462      * Fix the modes on the RCS files.  The user modes of the original
1463      * user file are propagated to the group and other modes as allowed
1464      * by the repository umask, except that all write permissions are
1465      * turned off.
1466      */
1467     mode = (sb.st_mode |
1468 	    (sb.st_mode & S_IRWXU) >> 3 |
1469 	    (sb.st_mode & S_IRWXU) >> 6) &
1470 	   ~cvsumask &
1471 	   ~(S_IWRITE | S_IWGRP | S_IWOTH);
1472     if (chmod (rcs, mode) < 0)
1473     {
1474 	ierrno = errno;
1475 	if (add_logfp != NULL)
1476 	    fperrmsg (add_logfp, 0, ierrno,
1477 		      "WARNING: cannot change mode of file %s", rcs);
1478 	error (0, ierrno, "WARNING: cannot change mode of file %s", rcs);
1479 	err++;
1480     }
1481     if (tocvsPath)
1482 	if (unlink_file_dir (tocvsPath) < 0)
1483 		error (0, errno, "cannot remove %s", tocvsPath);
1484     if (free_opt != NULL)
1485 	free (free_opt);
1486     return err;
1487 
1488 write_error:
1489     ierrno = errno;
1490     if (fclose (fprcs) < 0)
1491 	error (0, errno, "cannot close %s", rcs);
1492 write_error_noclose:
1493     if (fclose (fpuser) < 0)
1494 	error (0, errno, "cannot close %s", user);
1495     if (add_logfp != NULL)
1496 	fperrmsg (add_logfp, 0, ierrno, "ERROR: cannot write file %s", rcs);
1497     error (0, ierrno, "ERROR: cannot write file %s", rcs);
1498     if (ierrno == ENOSPC)
1499     {
1500 	if (CVS_UNLINK (rcs) < 0)
1501 	    error (0, errno, "cannot remove %s", rcs);
1502 	if (add_logfp != NULL)
1503 	    fperrmsg (add_logfp, 0, 0, "ERROR: out of space - aborting");
1504 	error (1, 0, "ERROR: out of space - aborting");
1505     }
1506 read_error:
1507     if (tocvsPath)
1508 	if (unlink_file_dir (tocvsPath) < 0)
1509 	    error (0, errno, "cannot remove %s", tocvsPath);
1510 
1511     if (free_opt != NULL)
1512 	free (free_opt);
1513 
1514     return err + 1;
1515 }
1516 
1517 #ifdef PRESERVE_PERMISSIONS_SUPPORT
1518 /* Write file permissions and symlink information for a file being
1519  * added into its RCS file.
1520  *
1521  * INPUTS
1522  *   fprcs	FILE pointer for the (newly-created) RCS file.  Permisisons
1523  *		and symlink information should be written here.
1524  *   userfile	Filename of the file being added.  (Used to read symbolic
1525  *		link contents, for symlinks.)
1526  *   file_type	File type of userfile, extracted from sbp->st_mode.
1527  *   sbp	'stat' information for userfile.
1528  *
1529  * RETURNS
1530  *   Return value is 0 for success, or nonzero for failure (in which case
1531  *   no error message has yet been printed).
1532  */
1533 static int
1534 preserve_initial_permissions (fprcs, userfile, file_type, sbp)
1535     FILE *fprcs;
1536     const char *userfile;
1537     mode_t file_type;
1538     struct stat *sbp;
1539 {
1540     if (file_type == S_IFLNK)
1541     {
1542 	char *link = Xreadlink (userfile, sbp->st_size);
1543 	if (fprintf (fprcs, "symlink\t@") < 0 ||
1544 	    expand_at_signs (link, strlen (link), fprcs) < 0 ||
1545 	    fprintf (fprcs, "@;\012") < 0)
1546 	    goto write_error;
1547 	free (link);
1548     }
1549     else
1550     {
1551 	if (fprintf (fprcs, "owner\t%u;\012", sbp->st_uid) < 0)
1552 	    goto write_error;
1553 	if (fprintf (fprcs, "group\t%u;\012", sbp->st_gid) < 0)
1554 	    goto write_error;
1555 	if (fprintf (fprcs, "permissions\t%o;\012",
1556 		     sbp->st_mode & 07777) < 0)
1557 	    goto write_error;
1558 	switch (file_type)
1559 	{
1560 	    case S_IFREG: break;
1561 	    case S_IFCHR:
1562 	    case S_IFBLK:
1563 #ifdef HAVE_STRUCT_STAT_ST_RDEV
1564 		if (fprintf (fprcs, "special\t%s %lu;\012",
1565 			     (file_type == S_IFCHR
1566 			      ? "character"
1567 			      : "block"),
1568 			     (unsigned long) sbp->st_rdev) < 0)
1569 		    goto write_error;
1570 #else
1571 		error (0, 0,
1572 "can't import %s: unable to import device files on this system",
1573 userfile);
1574 #endif
1575 		break;
1576 	    default:
1577 		error (0, 0,
1578 		       "can't import %s: unknown kind of special file",
1579 		       userfile);
1580 	}
1581     }
1582     return 0;
1583 
1584 write_error:
1585     return 1;
1586 }
1587 #endif /* PRESERVE_PERMISSIONS_SUPPORT */
1588 
1589 /* Copy file contents into an RCS file, expanding at signs.
1590  *
1591  * If config->preserve_perms is set, nothing is copied if the source is not
1592  * a regular file.
1593  *
1594  * INPUTS
1595  *   fprcs	FILE pointer for the (newly-created) RCS file.  The expanded
1596  *		contents should be written here.
1597  *   file_type	File type of the data source.  No data is copied if
1598  *		preserve_permissions is set and the source is not a
1599  *		regular file.
1600  *   user	Filename of the data source (used to print error messages).
1601  *   fpuser	FILE pointer for the data source, whose data is being
1602  *		copied into the RCS file.
1603  *
1604  * RETURNS
1605  *   Return value is 0 for success, or nonzero for failure (in which case
1606  *   no error message has yet been printed).
1607  */
1608 static int
1609 expand_and_copy_contents (fprcs, file_type, user, fpuser)
1610     FILE *fprcs, *fpuser;
1611     mode_t file_type;
1612     const char *user;
1613 {
1614     if (
1615 #ifdef PRESERVE_PERMISSIONS_SUPPORT
1616 	!config->preserve_perms ||
1617 #endif /* PRESERVE_PERMISSIONS_SUPPORT */
1618 	file_type == S_IFREG)
1619     {
1620 	char buf[8192];
1621 	unsigned int len;
1622 
1623 	while (1)
1624 	{
1625 	    len = fread (buf, 1, sizeof buf, fpuser);
1626 	    if (len == 0)
1627 	    {
1628 		if (ferror (fpuser))
1629 		    error (1, errno, "cannot read file %s for copying",
1630 			   user);
1631 		break;
1632 	    }
1633 	    if (expand_at_signs (buf, len, fprcs) < 0)
1634 		goto write_error;
1635 	}
1636     }
1637     return 0;
1638 
1639 write_error:
1640     return 1;
1641 }
1642 
1643 /*
1644  * Write SIZE bytes at BUF to FP, expanding @ signs into double @
1645  * signs.  If an error occurs, return a negative value and set errno
1646  * to indicate the error.  If not, return a nonnegative value.
1647  */
1648 int
1649 expand_at_signs (const char *buf, size_t size, FILE *fp)
1650 {
1651     register const char *cp, *next;
1652 
1653     cp = buf;
1654     while ((next = memchr (cp, '@', size)) != NULL)
1655     {
1656 	size_t len = ++next - cp;
1657 	if (fwrite (cp, 1, len, fp) != len)
1658 	    return EOF;
1659 	if (putc ('@', fp) == EOF)
1660 	    return EOF;
1661 	cp = next;
1662 	size -= len;
1663     }
1664 
1665     if (fwrite (cp, 1, size, fp) != size)
1666 	return EOF;
1667 
1668     return 1;
1669 }
1670 
1671 /*
1672  * Write an update message to (potentially) the screen and the log file.
1673  */
1674 static void
1675 add_log (int ch, char *fname)
1676 {
1677     if (!really_quiet)			/* write to terminal */
1678     {
1679 	char buf[2];
1680 	buf[0] = ch;
1681 	buf[1] = ' ';
1682 	cvs_output (buf, 2);
1683 	if (repos_len)
1684 	{
1685 	    cvs_output (repository + repos_len + 1, 0);
1686 	    cvs_output ("/", 1);
1687 	}
1688 	else if (repository[0] != '\0')
1689 	{
1690 	    cvs_output (repository, 0);
1691 	    cvs_output ("/", 1);
1692 	}
1693 	cvs_output (fname, 0);
1694 	cvs_output ("\n", 1);
1695     }
1696 
1697     if (repos_len)			/* write to logfile */
1698 	(void) fprintf (logfp, "%c %s/%s\n", ch,
1699 			repository + repos_len + 1, fname);
1700     else if (repository[0])
1701 	(void) fprintf (logfp, "%c %s/%s\n", ch, repository, fname);
1702     else
1703 	(void) fprintf (logfp, "%c %s\n", ch, fname);
1704 }
1705 
1706 /*
1707  * This is the recursive function that walks the argument directory looking
1708  * for sub-directories that have CVS administration files in them and updates
1709  * them recursively.
1710  *
1711  * Note that we do not follow symbolic links here, which is a feature!
1712  */
1713 static int
1714 import_descend_dir (char *message, char *dir, char *vtag, int targc,
1715 		    char **targv)
1716 {
1717     struct saved_cwd cwd;
1718     char *cp;
1719     int ierrno, err;
1720     char *rcs = NULL;
1721 
1722     if (islink (dir))
1723 	return 0;
1724     if (save_cwd (&cwd))
1725     {
1726 	fperrmsg (logfp, 0, errno, "Failed to save current directory.");
1727 	return 1;
1728     }
1729 
1730     /* Concatenate DIR to the end of REPOSITORY.  */
1731     if (repository[0] == '\0')
1732     {
1733 	char *new = xstrdup (dir);
1734 	free (repository);
1735 	repository = new;
1736     }
1737     else
1738     {
1739 	char *new = Xasprintf ("%s/%s", repository, dir);
1740 	free (repository);
1741 	repository = new;
1742     }
1743 
1744     if (!quiet && !current_parsed_root->isremote)
1745 	error (0, 0, "Importing %s", repository);
1746 
1747     if (CVS_CHDIR (dir) < 0)
1748     {
1749 	ierrno = errno;
1750 	fperrmsg (logfp, 0, ierrno, "ERROR: cannot chdir to %s", repository);
1751 	error (0, ierrno, "ERROR: cannot chdir to %s", repository);
1752 	err = 1;
1753 	goto out;
1754     }
1755     if (!current_parsed_root->isremote && !isdir (repository))
1756     {
1757 	rcs = Xasprintf ("%s%s", repository, RCSEXT);
1758 	if (isfile (repository) || isfile (rcs))
1759 	{
1760 	    fperrmsg (logfp, 0, 0,
1761 		      "ERROR: %s is a file, should be a directory!",
1762 		      repository);
1763 	    error (0, 0, "ERROR: %s is a file, should be a directory!",
1764 		   repository);
1765 	    err = 1;
1766 	    goto out;
1767 	}
1768 	if (noexec == 0 && CVS_MKDIR (repository, 0777) < 0)
1769 	{
1770 	    ierrno = errno;
1771 	    fperrmsg (logfp, 0, ierrno,
1772 		      "ERROR: cannot mkdir %s -- not added", repository);
1773 	    error (0, ierrno,
1774 		   "ERROR: cannot mkdir %s -- not added", repository);
1775 	    err = 1;
1776 	    goto out;
1777 	}
1778     }
1779     err = import_descend (message, vtag, targc, targv);
1780   out:
1781     if (rcs != NULL)
1782 	free (rcs);
1783     if ((cp = strrchr (repository, '/')) != NULL)
1784 	*cp = '\0';
1785     else
1786 	repository[0] = '\0';
1787     if (restore_cwd (&cwd))
1788 	error (1, errno, "Failed to restore current directory, `%s'.",
1789 	       cwd.name);
1790     free_cwd (&cwd);
1791     return err;
1792 }
1793