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