1 /* CVS client-related stuff. 2 3 This program is free software; you can redistribute it and/or modify 4 it under the terms of the GNU General Public License as published by 5 the Free Software Foundation; either version 2, or (at your option) 6 any later version. 7 8 This program is distributed in the hope that it will be useful, 9 but WITHOUT ANY WARRANTY; without even the implied warranty of 10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 GNU General Public License for more details. */ 12 13 #ifdef HAVE_CONFIG_H 14 # include "config.h" 15 #endif /* HAVE_CONFIG_H */ 16 17 #include "cvs.h" 18 #include "getline.h" 19 #include "edit.h" 20 #include "buffer.h" 21 #include "save-cwd.h" 22 23 #ifdef CLIENT_SUPPORT 24 25 # include "log-buffer.h" 26 # include "md5.h" 27 28 #include "socket-client.h" 29 #include "rsh-client.h" 30 31 # ifdef HAVE_GSSAPI 32 # include "gssapi-client.h" 33 # endif 34 35 # ifdef HAVE_KERBEROS 36 # include "kerberos4-client.h" 37 # endif 38 39 40 41 /* Keep track of any paths we are sending for Max-dotdot so that we can verify 42 * that uplevel paths coming back form the server are valid. 43 * 44 * FIXME: The correct way to do this is probably provide some sort of virtual 45 * path map on the client side. This would be generic enough to be applied to 46 * absolute paths supplied by the user too. 47 */ 48 static List *uppaths; 49 50 51 52 static void add_prune_candidate (const char *); 53 54 /* All the commands. */ 55 int add (int argc, char **argv); 56 int admin (int argc, char **argv); 57 int checkout (int argc, char **argv); 58 int commit (int argc, char **argv); 59 int diff (int argc, char **argv); 60 int history (int argc, char **argv); 61 int import (int argc, char **argv); 62 int cvslog (int argc, char **argv); 63 int patch (int argc, char **argv); 64 int release (int argc, char **argv); 65 int cvsremove (int argc, char **argv); 66 int rtag (int argc, char **argv); 67 int status (int argc, char **argv); 68 int tag (int argc, char **argv); 69 int update (int argc, char **argv); 70 71 #if defined AUTH_CLIENT_SUPPORT || defined HAVE_KERBEROS || defined HAVE_GSSAPI 72 static int connect_to(char *, unsigned int); 73 #endif 74 75 static size_t try_read_from_server (char *, size_t); 76 77 static void auth_server (cvsroot_t *, struct buffer *, struct buffer *, 78 int, int); 79 80 81 82 /* This is the referrer who referred us to a primary, or write server, using 83 * the "Redirect" request. 84 */ 85 static cvsroot_t *client_referrer; 86 87 /* We need to keep track of the list of directories we've sent to the 88 server. This list, along with the current CVSROOT, will help us 89 decide which command-line arguments to send. */ 90 List *dirs_sent_to_server; 91 static int 92 is_arg_a_parent_or_listed_dir (Node *n, void *d) 93 { 94 char *directory = n->key; /* name of the dir sent to server */ 95 char *this_argv_elem = d; /* this argv element */ 96 97 /* Say we should send this argument if the argument matches the 98 beginning of a directory name sent to the server. This way, 99 the server will know to start at the top of that directory 100 hierarchy and descend. */ 101 102 if (!strncmp (directory, this_argv_elem, strlen (this_argv_elem))) 103 return 1; 104 105 return 0; 106 } 107 108 109 110 /* Return nonzero if this argument should not be sent to the 111 server. */ 112 static int 113 arg_should_not_be_sent_to_server (char *arg) 114 { 115 /* Decide if we should send this directory name to the server. We 116 should always send argv[i] if: 117 118 1) the list of directories sent to the server is empty (as it 119 will be for checkout, etc.). 120 121 2) the argument is "." 122 123 3) the argument is a file in the cwd and the cwd is checked out 124 from the current root 125 126 4) the argument lies within one of the paths in 127 dirs_sent_to_server. 128 129 */ 130 131 if (list_isempty (dirs_sent_to_server)) 132 return 0; /* always send it */ 133 134 if (!strcmp (arg, ".")) 135 return 0; /* always send it */ 136 137 /* We should send arg if it is one of the directories sent to the 138 server or the parent of one; this tells the server to descend 139 the hierarchy starting at this level. */ 140 if (isdir (arg)) 141 { 142 if (walklist (dirs_sent_to_server, is_arg_a_parent_or_listed_dir, arg)) 143 return 0; 144 145 /* If arg wasn't a parent, we don't know anything about it (we 146 would have seen something related to it during the 147 send_files phase). Don't send it. */ 148 return 1; 149 } 150 151 /* Try to decide whether we should send arg to the server by 152 checking the contents of the corresponding CVSADM directory. */ 153 { 154 char *t, *root_string; 155 cvsroot_t *this_root = NULL; 156 157 /* Calculate "dirname arg" */ 158 for (t = arg + strlen (arg) - 1; t >= arg; t--) 159 { 160 if (ISSLASH (*t)) 161 break; 162 } 163 164 /* Now we're either poiting to the beginning of the 165 string, or we found a path separator. */ 166 if (t >= arg) 167 { 168 /* Found a path separator. */ 169 char c = *t; 170 *t = '\0'; 171 172 /* First, check to see if we sent this directory to the 173 server, because it takes less time than actually 174 opening the stuff in the CVSADM directory. */ 175 if (walklist (dirs_sent_to_server, is_arg_a_parent_or_listed_dir, 176 arg)) 177 { 178 *t = c; /* make sure to un-truncate the arg */ 179 return 0; 180 } 181 182 /* Since we didn't find it in the list, check the CVSADM 183 files on disk. */ 184 this_root = Name_Root (arg, NULL); 185 root_string = this_root->original; 186 *t = c; 187 } 188 else 189 { 190 /* We're at the beginning of the string. Look at the 191 CVSADM files in cwd. */ 192 if (CVSroot_cmdline) 193 root_string = CVSroot_cmdline; 194 else 195 { 196 this_root = Name_Root (NULL, NULL); 197 root_string = this_root->original; 198 } 199 } 200 201 /* Now check the value for root. */ 202 if (root_string && current_parsed_root 203 && strcmp (root_string, original_parsed_root->original)) 204 { 205 /* Don't send this, since the CVSROOTs don't match. */ 206 return 1; 207 } 208 } 209 210 /* OK, let's send it. */ 211 return 0; 212 } 213 #endif /* CLIENT_SUPPORT */ 214 215 216 217 #if defined(CLIENT_SUPPORT) || defined(SERVER_SUPPORT) 218 219 /* Shared with server. */ 220 221 /* 222 * Return a malloc'd, '\0'-terminated string 223 * corresponding to the mode in SB. 224 */ 225 char * 226 mode_to_string (mode_t mode) 227 { 228 char u[4], g[4], o[4]; 229 int i; 230 231 i = 0; 232 if (mode & S_IRUSR) u[i++] = 'r'; 233 if (mode & S_IWUSR) u[i++] = 'w'; 234 if (mode & S_IXUSR) u[i++] = 'x'; 235 u[i] = '\0'; 236 237 i = 0; 238 if (mode & S_IRGRP) g[i++] = 'r'; 239 if (mode & S_IWGRP) g[i++] = 'w'; 240 if (mode & S_IXGRP) g[i++] = 'x'; 241 g[i] = '\0'; 242 243 i = 0; 244 if (mode & S_IROTH) o[i++] = 'r'; 245 if (mode & S_IWOTH) o[i++] = 'w'; 246 if (mode & S_IXOTH) o[i++] = 'x'; 247 o[i] = '\0'; 248 249 return Xasprintf ("u=%s,g=%s,o=%s", u, g, o); 250 } 251 252 253 254 /* 255 * Change mode of FILENAME to MODE_STRING. 256 * Returns 0 for success or errno code. 257 * If RESPECT_UMASK is set, then honor the umask. 258 */ 259 int 260 change_mode (const char *filename, const char *mode_string, int respect_umask) 261 { 262 #ifdef CHMOD_BROKEN 263 char *p; 264 int writeable = 0; 265 266 /* We can only distinguish between 267 1) readable 268 2) writeable 269 3) Picasso's "Blue Period" 270 We handle the first two. */ 271 p = mode_string; 272 while (*p != '\0') 273 { 274 if ((p[0] == 'u' || p[0] == 'g' || p[0] == 'o') && p[1] == '=') 275 { 276 char *q = p + 2; 277 while (*q != ',' && *q != '\0') 278 { 279 if (*q == 'w') 280 writeable = 1; 281 ++q; 282 } 283 } 284 /* Skip to the next field. */ 285 while (*p != ',' && *p != '\0') 286 ++p; 287 if (*p == ',') 288 ++p; 289 } 290 291 /* xchmod honors the umask for us. In the !respect_umask case, we 292 don't try to cope with it (probably to handle that well, the server 293 needs to deal with modes in data structures, rather than via the 294 modes in temporary files). */ 295 xchmod (filename, writeable); 296 return 0; 297 298 #else /* ! CHMOD_BROKEN */ 299 300 const char *p; 301 mode_t mode = 0; 302 mode_t oumask; 303 304 p = mode_string; 305 while (*p != '\0') 306 { 307 if ((p[0] == 'u' || p[0] == 'g' || p[0] == 'o') && p[1] == '=') 308 { 309 int can_read = 0, can_write = 0, can_execute = 0; 310 const char *q = p + 2; 311 while (*q != ',' && *q != '\0') 312 { 313 if (*q == 'r') 314 can_read = 1; 315 else if (*q == 'w') 316 can_write = 1; 317 else if (*q == 'x') 318 can_execute = 1; 319 ++q; 320 } 321 if (p[0] == 'u') 322 { 323 if (can_read) 324 mode |= S_IRUSR; 325 if (can_write) 326 mode |= S_IWUSR; 327 if (can_execute) 328 mode |= S_IXUSR; 329 } 330 else if (p[0] == 'g') 331 { 332 if (can_read) 333 mode |= S_IRGRP; 334 if (can_write) 335 mode |= S_IWGRP; 336 if (can_execute) 337 mode |= S_IXGRP; 338 } 339 else if (p[0] == 'o') 340 { 341 if (can_read) 342 mode |= S_IROTH; 343 if (can_write) 344 mode |= S_IWOTH; 345 if (can_execute) 346 mode |= S_IXOTH; 347 } 348 } 349 /* Skip to the next field. */ 350 while (*p != ',' && *p != '\0') 351 ++p; 352 if (*p == ',') 353 ++p; 354 } 355 356 if (respect_umask) 357 { 358 oumask = umask (0); 359 (void) umask (oumask); 360 mode &= ~oumask; 361 } 362 363 if (chmod (filename, mode) < 0) 364 return errno; 365 return 0; 366 #endif /* ! CHMOD_BROKEN */ 367 } 368 #endif /* CLIENT_SUPPORT or SERVER_SUPPORT */ 369 370 371 372 #ifdef CLIENT_SUPPORT 373 int client_prune_dirs; 374 375 static List *ignlist = NULL; 376 377 /* Buffer to write to the server. */ 378 static struct buffer *global_to_server; 379 380 /* Buffer used to read from the server. */ 381 static struct buffer *global_from_server; 382 383 384 385 /* 386 * Read a line from the server. Result does not include the terminating \n. 387 * 388 * Space for the result is malloc'd and should be freed by the caller. 389 * 390 * Returns number of bytes read. 391 */ 392 static size_t 393 read_line_via (struct buffer *via_from_buffer, struct buffer *via_to_buffer, 394 char **resultp) 395 { 396 int status; 397 char *result; 398 size_t len; 399 400 status = buf_flush (via_to_buffer, 1); 401 if (status != 0) 402 error (1, status, "writing to server"); 403 404 status = buf_read_line (via_from_buffer, &result, &len); 405 if (status != 0) 406 { 407 if (status == -1) 408 error (1, 0, 409 "end of file from server (consult above messages if any)"); 410 else if (status == -2) 411 error (1, 0, "out of memory"); 412 else 413 error (1, status, "reading from server"); 414 } 415 416 if (resultp) 417 *resultp = result; 418 else 419 free (result); 420 421 return len; 422 } 423 424 425 426 static size_t 427 read_line (char **resultp) 428 { 429 return read_line_via (global_from_server, global_to_server, resultp); 430 } 431 #endif /* CLIENT_SUPPORT */ 432 433 434 435 #if defined(CLIENT_SUPPORT) || defined(SERVER_SUPPORT) 436 /* 437 * Zero if compression isn't supported or requested; non-zero to indicate 438 * a compression level to request from gzip. 439 */ 440 int gzip_level; 441 442 /* 443 * Level of compression to use when running gzip on a single file. 444 */ 445 int file_gzip_level; 446 447 #endif /* CLIENT_SUPPORT or SERVER_SUPPORT */ 448 449 #ifdef CLIENT_SUPPORT 450 451 /* Whether the server asked us to force compression. */ 452 static bool force_gzip; 453 454 /* 455 * The Repository for the top level of this command (not necessarily 456 * the CVSROOT, just the current directory at the time we do it). 457 */ 458 static char *toplevel_repos; 459 460 /* Working directory when we first started. Note: we could speed things 461 up on some systems by using savecwd.h here instead of just always 462 storing a name. */ 463 char *toplevel_wd; 464 465 466 467 static void 468 handle_ok (char *args, size_t len) 469 { 470 return; 471 } 472 473 474 475 static void 476 handle_error (char *args, size_t len) 477 { 478 int something_printed; 479 480 /* 481 * First there is a symbolic error code followed by a space, which 482 * we ignore. 483 */ 484 char *p = strchr (args, ' '); 485 if (!p) 486 { 487 error (0, 0, "invalid data from cvs server"); 488 return; 489 } 490 ++p; 491 492 /* Next we print the text of the message from the server. We 493 probably should be prefixing it with "server error" or some 494 such, because if it is something like "Out of memory", the 495 current behavior doesn't say which machine is out of 496 memory. */ 497 498 len -= p - args; 499 something_printed = 0; 500 for (; len > 0; --len) 501 { 502 something_printed = 1; 503 putc (*p++, stderr); 504 } 505 if (something_printed) 506 putc ('\n', stderr); 507 } 508 509 510 511 static void 512 handle_valid_requests (char *args, size_t len) 513 { 514 char *p = args; 515 char *q; 516 struct request *rq; 517 do 518 { 519 q = strchr (p, ' '); 520 if (q) 521 *q++ = '\0'; 522 for (rq = requests; rq->name; ++rq) 523 { 524 if (!strcmp (rq->name, p)) 525 break; 526 } 527 if (!rq->name) 528 /* 529 * It is a request we have never heard of (and thus never 530 * will want to use). So don't worry about it. 531 */ 532 ; 533 else 534 { 535 if (rq->flags & RQ_ENABLEME) 536 { 537 /* 538 * Server wants to know if we have this, to enable the 539 * feature. 540 */ 541 send_to_server (rq->name, 0); 542 send_to_server ("\012", 0); 543 } 544 else 545 rq->flags |= RQ_SUPPORTED; 546 } 547 p = q; 548 } while (q); 549 for (rq = requests; rq->name; ++rq) 550 { 551 if ((rq->flags & RQ_SUPPORTED) 552 || (rq->flags & RQ_ENABLEME)) 553 continue; 554 if (rq->flags & RQ_ESSENTIAL) 555 error (1, 0, "request `%s' not supported by server", rq->name); 556 } 557 } 558 559 static void 560 handle_force_gzip (char *args, size_t len) 561 { 562 force_gzip = true; 563 } 564 565 566 567 /* Has the server told us its name since the last redirect? 568 */ 569 static bool referred_since_last_redirect = false; 570 static bool free_client_referrer = false; 571 572 573 574 static void 575 handle_referrer (char *args, size_t len) 576 { 577 TRACE (TRACE_FUNCTION, "handle_referrer (%s)", args); 578 client_referrer = parse_cvsroot (args); 579 referred_since_last_redirect = true; 580 free_client_referrer = true; 581 } 582 583 584 585 /* Redirect our connection to a different server and start over. 586 * 587 * GLOBALS 588 * current_parsed_root The CVSROOT being accessed. 589 * client_referrer Used to track the server which referred us to a 590 * new server. Can be supplied by the referring 591 * server. 592 * free_client_referrer Used to track whether the client_referrer needs 593 * to be freed before changing it. 594 * referred_since_last_redirect 595 * Tracks whether the currect server told us how 596 * to refer to it. 597 * 598 * OUTPUTS 599 * current_parsed_root Updated to point to the new CVSROOT. 600 * referred_since_last_redirect 601 * Always cleared. 602 * client_referrer Set automatically to current_parsed_root if 603 * the current server did not give us a name to 604 * refer to it by. 605 * free_client_referrer Reset when necessary. 606 */ 607 static void 608 handle_redirect (char *args, size_t len) 609 { 610 static List *redirects = NULL; 611 612 TRACE (TRACE_FUNCTION, "handle_redirect (%s)", args); 613 614 if (redirects && findnode (redirects, args)) 615 error (1, 0, "`Redirect' loop detected. Server misconfiguration?"); 616 else 617 { 618 if (!redirects) redirects = getlist(); 619 push_string (redirects, args); 620 } 621 622 if (referred_since_last_redirect) 623 referred_since_last_redirect = false; 624 else 625 { 626 if (free_client_referrer) free (client_referrer); 627 client_referrer = current_parsed_root; 628 free_client_referrer = false; 629 } 630 631 current_parsed_root = parse_cvsroot (args); 632 633 /* We deliberately do not set ORIGINAL_PARSED_ROOT here. 634 * ORIGINAL_PARSED_ROOT is used by the client to determine the current root 635 * being processed for the purpose of looking it up in lists and such, even 636 * after a redirect. 637 * 638 * FIXME 639 * CURRENT_PARSED_ROOT should not be reset by this function. Redirects 640 * should be "added" to it. The REDIRECTS list should also be replaced 641 * by this new CURRENT_PARSED_ROOT element. This way, if, for instance, 642 * a multi-root workspace had two secondaries pointing to the same 643 * primary, then the client would not report a looping error. 644 * 645 * There is also a potential memory leak above and storing new roots as 646 * part of the original could help avoid it fairly elegantly. 647 */ 648 if (!current_parsed_root) 649 error (1, 0, "Server requested redirect to invalid root: `%s'", 650 args); 651 } 652 653 654 655 /* 656 * This is a proc for walklist(). It inverts the error return premise of 657 * walklist. 658 * 659 * RETURNS 660 * True If this path is prefixed by one of the paths in walklist and 661 * does not step above the prefix path. 662 * False Otherwise. 663 */ 664 static 665 int path_list_prefixed (Node *p, void *closure) 666 { 667 const char *questionable = closure; 668 const char *prefix = p->key; 669 if (strncmp (prefix, questionable, strlen (prefix))) return 0; 670 questionable += strlen (prefix); 671 while (ISSLASH (*questionable)) questionable++; 672 if (*questionable == '\0') return 1; 673 return pathname_levels (questionable); 674 } 675 676 677 678 /* 679 * Need to validate the client pathname. Disallowed paths include: 680 * 681 * 1. Absolute paths. 682 * 2. Pathnames that do not reference a specifically requested update 683 * directory. 684 * 685 * In case 2, we actually only check that the directory is under the uppermost 686 * directories mentioned on the command line. 687 * 688 * RETURNS 689 * True If the path is valid. 690 * False Otherwise. 691 */ 692 static 693 int is_valid_client_path (const char *pathname) 694 { 695 /* 1. Absolute paths. */ 696 if (ISABSOLUTE (pathname)) return 0; 697 /* 2. No up-references in path. */ 698 if (pathname_levels (pathname) == 0) return 1; 699 /* 2. No Max-dotdot paths registered. */ 700 if (!uppaths) return 0; 701 702 return walklist (uppaths, path_list_prefixed, (void *)pathname); 703 } 704 705 706 707 /* 708 * Do all the processing for PATHNAME, where pathname consists of the 709 * repository and the filename. The parameters we pass to FUNC are: 710 * DATA is just the DATA parameter which was passed to 711 * call_in_directory; ENT_LIST is a pointer to an entries list (which 712 * we manage the storage for); SHORT_PATHNAME is the pathname of the 713 * file relative to the (overall) directory in which the command is 714 * taking place; and FILENAME is the filename portion only of 715 * SHORT_PATHNAME. When we call FUNC, the curent directory points to 716 * the directory portion of SHORT_PATHNAME. */ 717 static void 718 call_in_directory (const char *pathname, 719 void (*func) (void *, List *, const char *, const char *), 720 void *data) 721 { 722 /* This variable holds the result of Entries_Open. */ 723 List *last_entries = NULL; 724 char *dir_name; 725 char *filename; 726 /* This is what we get when we hook up the directory (working directory 727 name) from PATHNAME with the filename from REPOSNAME. For example: 728 pathname: ccvs/src/ 729 reposname: /u/src/master/ccvs/foo/ChangeLog 730 short_pathname: ccvs/src/ChangeLog 731 */ 732 char *short_pathname; 733 char *p; 734 735 /* 736 * Do the whole descent in parallel for the repositories, so we 737 * know what to put in CVS/Repository files. I'm not sure the 738 * full hair is necessary since the server does a similar 739 * computation; I suspect that we only end up creating one 740 * directory at a time anyway. 741 * 742 * Also note that we must *only* worry about this stuff when we 743 * are creating directories; `cvs co foo/bar; cd foo/bar; cvs co 744 * CVSROOT; cvs update' is legitimate, but in this case 745 * foo/bar/CVSROOT/CVS/Repository is not a subdirectory of 746 * foo/bar/CVS/Repository. 747 */ 748 char *reposname; 749 char *short_repos; 750 char *reposdirname; 751 char *rdirp; 752 int reposdirname_absolute; 753 int newdir = 0; 754 755 assert (pathname); 756 757 reposname = NULL; 758 read_line (&reposname); 759 assert (reposname); 760 761 reposdirname_absolute = 0; 762 if (strncmp (reposname, toplevel_repos, strlen (toplevel_repos))) 763 { 764 reposdirname_absolute = 1; 765 short_repos = reposname; 766 } 767 else 768 { 769 short_repos = reposname + strlen (toplevel_repos) + 1; 770 if (short_repos[-1] != '/') 771 { 772 reposdirname_absolute = 1; 773 short_repos = reposname; 774 } 775 } 776 777 /* Now that we have SHORT_REPOS, we can calculate the path to the file we 778 * are being requested to operate on. 779 */ 780 filename = strrchr (short_repos, '/'); 781 if (!filename) 782 filename = short_repos; 783 else 784 ++filename; 785 786 short_pathname = xmalloc (strlen (pathname) + strlen (filename) + 5); 787 strcpy (short_pathname, pathname); 788 strcat (short_pathname, filename); 789 790 /* Now that we know the path to the file we were requested to operate on, 791 * we can verify that it is valid. 792 * 793 * For security reasons, if SHORT_PATHNAME is absolute or attempts to 794 * ascend outside of the current sanbbox, we abort. The server should not 795 * send us anything but relative paths which remain inside the sandbox 796 * here. Anything less means a trojan CVS server could create and edit 797 * arbitrary files on the client. 798 */ 799 if (!is_valid_client_path (short_pathname)) 800 { 801 error (0, 0, 802 "Server attempted to update a file via an invalid pathname:"); 803 error (1, 0, "`%s'.", short_pathname); 804 } 805 806 reposdirname = xstrdup (short_repos); 807 p = strrchr (reposdirname, '/'); 808 if (!p) 809 { 810 reposdirname = xrealloc (reposdirname, 2); 811 reposdirname[0] = '.'; reposdirname[1] = '\0'; 812 } 813 else 814 *p = '\0'; 815 816 dir_name = xstrdup (pathname); 817 p = strrchr (dir_name, '/'); 818 if (!p) 819 { 820 dir_name = xrealloc (dir_name, 2); 821 dir_name[0] = '.'; dir_name[1] = '\0'; 822 } 823 else 824 *p = '\0'; 825 if (client_prune_dirs) 826 add_prune_candidate (dir_name); 827 828 if (!toplevel_wd) 829 { 830 toplevel_wd = xgetcwd (); 831 if (!toplevel_wd) 832 error (1, errno, "could not get working directory"); 833 } 834 835 if (CVS_CHDIR (toplevel_wd) < 0) 836 error (1, errno, "could not chdir to %s", toplevel_wd); 837 838 /* Create the CVS directory at the top level if needed. The 839 isdir seems like an unneeded system call, but it *does* 840 need to be called both if the CVS_CHDIR below succeeds 841 (e.g. "cvs co .") or if it fails (e.g. basicb-1a in 842 testsuite). We only need to do this for the "." case, 843 since the server takes care of forcing this directory to be 844 created in all other cases. If we don't create CVSADM 845 here, the call to Entries_Open below will fail. FIXME: 846 perhaps this means that we should change our algorithm 847 below that calls Create_Admin instead of having this code 848 here? */ 849 if (/* I think the reposdirname_absolute case has to do with 850 things like "cvs update /foo/bar". In any event, the 851 code below which tries to put toplevel_repos into 852 CVS/Repository is almost surely unsuited to 853 the reposdirname_absolute case. */ 854 !reposdirname_absolute 855 && !strcmp (dir_name, ".") 856 && ! isdir (CVSADM)) 857 { 858 char *repo; 859 char *r; 860 861 newdir = 1; 862 863 /* If toplevel_repos doesn't have at least one character, then the 864 * reference to r[-1] below could be out of bounds. 865 */ 866 assert (*toplevel_repos); 867 868 repo = xmalloc (strlen (toplevel_repos) 869 + 10); 870 strcpy (repo, toplevel_repos); 871 r = repo + strlen (repo); 872 if (r[-1] != '.' || r[-2] != '/') 873 strcpy (r, "/."); 874 875 Create_Admin (".", ".", repo, NULL, NULL, 0, 1, 1); 876 877 free (repo); 878 } 879 880 if (CVS_CHDIR (dir_name) < 0) 881 { 882 char *dir; 883 char *dirp; 884 885 if (! existence_error (errno)) 886 error (1, errno, "could not chdir to %s", dir_name); 887 888 /* Directory does not exist, we need to create it. */ 889 newdir = 1; 890 891 /* Provided we are willing to assume that directories get 892 created one at a time, we could simplify this a lot. 893 Do note that one aspect still would need to walk the 894 dir_name path: the checking for "fncmp (dir, CVSADM)". */ 895 896 dir = xmalloc (strlen (dir_name) + 1); 897 dirp = dir_name; 898 rdirp = reposdirname; 899 900 /* This algorithm makes nested directories one at a time 901 and create CVS administration files in them. For 902 example, we're checking out foo/bar/baz from the 903 repository: 904 905 1) create foo, point CVS/Repository to <root>/foo 906 2) .. foo/bar .. <root>/foo/bar 907 3) .. foo/bar/baz .. <root>/foo/bar/baz 908 909 As you can see, we're just stepping along DIR_NAME (with 910 DIRP) and REPOSDIRNAME (with RDIRP) respectively. 911 912 We need to be careful when we are checking out a 913 module, however, since DIR_NAME and REPOSDIRNAME are not 914 going to be the same. Since modules will not have any 915 slashes in their names, we should watch the output of 916 STRCHR to decide whether or not we should use STRCHR on 917 the RDIRP. That is, if we're down to a module name, 918 don't keep picking apart the repository directory name. */ 919 920 do 921 { 922 dirp = strchr (dirp, '/'); 923 if (dirp) 924 { 925 strncpy (dir, dir_name, dirp - dir_name); 926 dir[dirp - dir_name] = '\0'; 927 /* Skip the slash. */ 928 ++dirp; 929 if (!rdirp) 930 /* This just means that the repository string has 931 fewer components than the dir_name string. But 932 that is OK (e.g. see modules3-8 in testsuite). */ 933 ; 934 else 935 rdirp = strchr (rdirp, '/'); 936 } 937 else 938 { 939 /* If there are no more slashes in the dir name, 940 we're down to the most nested directory -OR- to 941 the name of a module. In the first case, we 942 should be down to a DIRP that has no slashes, 943 so it won't help/hurt to do another STRCHR call 944 on DIRP. It will definitely hurt, however, if 945 we're down to a module name, since a module 946 name can point to a nested directory (that is, 947 DIRP will still have slashes in it. Therefore, 948 we should set it to NULL so the routine below 949 copies the contents of REMOTEDIRNAME onto the 950 root repository directory (does this if rdirp 951 is set to NULL, because we used to do an extra 952 STRCHR call here). */ 953 954 rdirp = NULL; 955 strcpy (dir, dir_name); 956 } 957 958 if (fncmp (dir, CVSADM) == 0) 959 { 960 error (0, 0, "cannot create a directory named %s", dir); 961 error (0, 0, "because CVS uses \"%s\" for its own uses", 962 CVSADM); 963 error (1, 0, "rename the directory and try again"); 964 } 965 966 if (mkdir_if_needed (dir)) 967 { 968 /* It already existed, fine. Just keep going. */ 969 } 970 else if (!strcmp (cvs_cmd_name, "export")) 971 /* Don't create CVSADM directories if this is export. */ 972 ; 973 else 974 { 975 /* 976 * Put repository in CVS/Repository. For historical 977 * (pre-CVS/Root) reasons, this is an absolute pathname, 978 * but what really matters is the part of it which is 979 * relative to cvsroot. 980 */ 981 char *repo; 982 char *r, *b; 983 984 repo = xmalloc (strlen (reposdirname) 985 + strlen (toplevel_repos) 986 + 80); 987 if (reposdirname_absolute) 988 r = repo; 989 else 990 { 991 strcpy (repo, toplevel_repos); 992 strcat (repo, "/"); 993 r = repo + strlen (repo); 994 } 995 996 if (rdirp) 997 { 998 /* See comment near start of function; the only 999 way that the server can put the right thing 1000 in each CVS/Repository file is to create the 1001 directories one at a time. I think that the 1002 CVS server has been doing this all along. */ 1003 error (0, 0, "\ 1004 warning: server is not creating directories one at a time"); 1005 strncpy (r, reposdirname, rdirp - reposdirname); 1006 r[rdirp - reposdirname] = '\0'; 1007 } 1008 else 1009 strcpy (r, reposdirname); 1010 1011 Create_Admin (dir, dir, repo, NULL, NULL, 0, 0, 1); 1012 free (repo); 1013 1014 b = strrchr (dir, '/'); 1015 if (!b) 1016 Subdir_Register (NULL, NULL, dir); 1017 else 1018 { 1019 *b = '\0'; 1020 Subdir_Register (NULL, dir, b + 1); 1021 *b = '/'; 1022 } 1023 } 1024 1025 if (rdirp) 1026 { 1027 /* Skip the slash. */ 1028 ++rdirp; 1029 } 1030 1031 } while (dirp); 1032 free (dir); 1033 /* Now it better work. */ 1034 if (CVS_CHDIR (dir_name) < 0) 1035 error (1, errno, "could not chdir to %s", dir_name); 1036 } 1037 else if (!strcmp (cvs_cmd_name, "export")) 1038 /* Don't create CVSADM directories if this is export. */ 1039 ; 1040 else if (!isdir (CVSADM)) 1041 { 1042 /* 1043 * Put repository in CVS/Repository. For historical 1044 * (pre-CVS/Root) reasons, this is an absolute pathname, 1045 * but what really matters is the part of it which is 1046 * relative to cvsroot. 1047 */ 1048 char *repo; 1049 1050 if (reposdirname_absolute) 1051 repo = reposdirname; 1052 else 1053 repo = Xasprintf ("%s/%s", toplevel_repos, reposdirname); 1054 1055 Create_Admin (".", ".", repo, NULL, NULL, 0, 1, 1); 1056 if (repo != reposdirname) 1057 free (repo); 1058 } 1059 1060 if (strcmp (cvs_cmd_name, "export")) 1061 { 1062 last_entries = Entries_Open (0, dir_name); 1063 1064 /* If this is a newly created directory, we will record 1065 all subdirectory information, so call Subdirs_Known in 1066 case there are no subdirectories. If this is not a 1067 newly created directory, it may be an old working 1068 directory from before we recorded subdirectory 1069 information in the Entries file. We force a search for 1070 all subdirectories now, to make sure our subdirectory 1071 information is up to date. If the Entries file does 1072 record subdirectory information, then this call only 1073 does list manipulation. */ 1074 if (newdir) 1075 Subdirs_Known (last_entries); 1076 else 1077 { 1078 List *dirlist; 1079 1080 dirlist = Find_Directories (NULL, W_LOCAL, last_entries); 1081 dellist (&dirlist); 1082 } 1083 } 1084 free (reposdirname); 1085 (*func) (data, last_entries, short_pathname, filename); 1086 if (last_entries) 1087 Entries_Close (last_entries); 1088 free (dir_name); 1089 free (short_pathname); 1090 free (reposname); 1091 } 1092 1093 1094 1095 static void 1096 copy_a_file (void *data, List *ent_list, const char *short_pathname, 1097 const char *filename) 1098 { 1099 char *newname; 1100 1101 read_line (&newname); 1102 1103 #ifdef USE_VMS_FILENAMES 1104 { 1105 /* Mogrify the filename so VMS is happy with it. */ 1106 char *p; 1107 for(p = newname; *p; p++) 1108 if(*p == '.' || *p == '#') *p = '_'; 1109 } 1110 #endif 1111 /* cvsclient.texi has said for a long time that newname must be in the 1112 same directory. Wouldn't want a malicious or buggy server overwriting 1113 ~/.profile, /etc/passwd, or anything like that. */ 1114 if (last_component (newname) != newname) 1115 error (1, 0, "protocol error: Copy-file tried to specify directory"); 1116 1117 if (unlink_file (newname) && !existence_error (errno)) 1118 error (0, errno, "unable to remove %s", newname); 1119 copy_file (filename, newname); 1120 free (newname); 1121 } 1122 1123 1124 1125 static void 1126 handle_copy_file (char *args, size_t len) 1127 { 1128 call_in_directory (args, copy_a_file, NULL); 1129 } 1130 1131 1132 1133 /* Read from the server the count for the length of a file, then read 1134 the contents of that file and write them to FILENAME. FULLNAME is 1135 the name of the file for use in error messages. FIXME-someday: 1136 extend this to deal with compressed files and make update_entries 1137 use it. On error, gives a fatal error. */ 1138 static void 1139 read_counted_file (const char *filename, const char *fullname) 1140 { 1141 char *size_string; 1142 size_t size; 1143 char *buf; 1144 1145 /* Pointers in buf to the place to put data which will be read, 1146 and the data which needs to be written, respectively. */ 1147 char *pread; 1148 char *pwrite; 1149 /* Number of bytes left to read and number of bytes in buf waiting to 1150 be written, respectively. */ 1151 size_t nread; 1152 size_t nwrite; 1153 1154 FILE *fp; 1155 1156 read_line (&size_string); 1157 if (size_string[0] == 'z') 1158 error (1, 0, "\ 1159 protocol error: compressed files not supported for that operation"); 1160 /* FIXME: should be doing more error checking, probably. Like using 1161 strtoul and making sure we used up the whole line. */ 1162 size = atoi (size_string); 1163 free (size_string); 1164 1165 /* A more sophisticated implementation would use only a limited amount 1166 of buffer space (8K perhaps), and read that much at a time. We allocate 1167 a buffer for the whole file only to make it easy to keep track what 1168 needs to be read and written. */ 1169 buf = xmalloc (size); 1170 1171 /* FIXME-someday: caller should pass in a flag saying whether it 1172 is binary or not. I haven't carefully looked into whether 1173 CVS/Template files should use local text file conventions or 1174 not. */ 1175 fp = CVS_FOPEN (filename, "wb"); 1176 if (!fp) 1177 error (1, errno, "cannot write %s", fullname); 1178 nread = size; 1179 nwrite = 0; 1180 pread = buf; 1181 pwrite = buf; 1182 while (nread > 0 || nwrite > 0) 1183 { 1184 size_t n; 1185 1186 if (nread > 0) 1187 { 1188 n = try_read_from_server (pread, nread); 1189 nread -= n; 1190 pread += n; 1191 nwrite += n; 1192 } 1193 1194 if (nwrite > 0) 1195 { 1196 n = fwrite (pwrite, sizeof *pwrite, nwrite, fp); 1197 if (ferror (fp)) 1198 error (1, errno, "cannot write %s", fullname); 1199 nwrite -= n; 1200 pwrite += n; 1201 } 1202 } 1203 free (buf); 1204 if (fclose (fp) < 0) 1205 error (1, errno, "cannot close %s", fullname); 1206 } 1207 1208 1209 1210 /* OK, we want to swallow the "U foo.c" response and then output it only 1211 if we can update the file. In the future we probably want some more 1212 systematic approach to parsing tagged text, but for now we keep it 1213 ad hoc. "Why," I hear you cry, "do we not just look at the 1214 Update-existing and Created responses?" That is an excellent question, 1215 and the answer is roughly conservatism/laziness--I haven't read through 1216 update.c enough to figure out the exact correspondence or lack thereof 1217 between those responses and a "U foo.c" line (note that Merged, from 1218 join_file, can be either "C foo" or "U foo" depending on the context). */ 1219 /* Nonzero if we have seen +updated and not -updated. */ 1220 static int updated_seen; 1221 /* Filename from an "fname" tagged response within +updated/-updated. */ 1222 static char *updated_fname; 1223 1224 /* This struct is used to hold data when reading the +importmergecmd 1225 and -importmergecmd tags. We put the variables in a struct only 1226 for namespace issues. FIXME: As noted above, we need to develop a 1227 more systematic approach. */ 1228 static struct 1229 { 1230 /* Nonzero if we have seen +importmergecmd and not -importmergecmd. */ 1231 int seen; 1232 /* Number of conflicts, from a "conflicts" tagged response. */ 1233 int conflicts; 1234 /* First merge tag, from a "mergetag1" tagged response. */ 1235 char *mergetag1; 1236 /* Second merge tag, from a "mergetag2" tagged response. */ 1237 char *mergetag2; 1238 /* Repository, from a "repository" tagged response. */ 1239 char *repository; 1240 } importmergecmd; 1241 1242 /* Nonzero if we should arrange to return with a failure exit status. */ 1243 static bool failure_exit; 1244 1245 1246 /* 1247 * The time stamp of the last file we registered. 1248 */ 1249 static time_t last_register_time; 1250 1251 1252 1253 /* 1254 * The Checksum response gives the checksum for the file transferred 1255 * over by the next Updated, Merged or Patch response. We just store 1256 * it here, and then check it in update_entries. 1257 */ 1258 static int stored_checksum_valid; 1259 static unsigned char stored_checksum[16]; 1260 static void 1261 handle_checksum (char *args, size_t len) 1262 { 1263 char *s; 1264 char buf[3]; 1265 int i; 1266 1267 if (stored_checksum_valid) 1268 error (1, 0, "Checksum received before last one was used"); 1269 1270 s = args; 1271 buf[2] = '\0'; 1272 for (i = 0; i < 16; i++) 1273 { 1274 char *bufend; 1275 1276 buf[0] = *s++; 1277 buf[1] = *s++; 1278 stored_checksum[i] = (char) strtol (buf, &bufend, 16); 1279 if (bufend != buf + 2) 1280 break; 1281 } 1282 1283 if (i < 16 || *s != '\0') 1284 error (1, 0, "Invalid Checksum response: `%s'", args); 1285 1286 stored_checksum_valid = 1; 1287 } 1288 1289 1290 1291 /* Mode that we got in a "Mode" response (malloc'd), or NULL if none. */ 1292 static char *stored_mode; 1293 static void 1294 handle_mode (char *args, size_t len) 1295 { 1296 if (stored_mode) 1297 error (1, 0, "protocol error: duplicate Mode"); 1298 stored_mode = xstrdup (args); 1299 } 1300 1301 1302 1303 /* Nonzero if time was specified in Mod-time. */ 1304 static int stored_modtime_valid; 1305 /* Time specified in Mod-time. */ 1306 static time_t stored_modtime; 1307 static void 1308 handle_mod_time (char *args, size_t len) 1309 { 1310 struct timespec newtime; 1311 if (stored_modtime_valid) 1312 error (0, 0, "protocol error: duplicate Mod-time"); 1313 if (get_date (&newtime, args, NULL)) 1314 { 1315 /* Truncate nanoseconds. */ 1316 stored_modtime = newtime.tv_sec; 1317 stored_modtime_valid = 1; 1318 } 1319 else 1320 error (0, 0, "protocol error: cannot parse date %s", args); 1321 } 1322 1323 1324 1325 /* 1326 * If we receive a patch, but the patch program fails to apply it, we 1327 * want to request the original file. We keep a list of files whose 1328 * patches have failed. 1329 */ 1330 1331 char **failed_patches; 1332 int failed_patches_count; 1333 1334 struct update_entries_data 1335 { 1336 enum { 1337 /* 1338 * We are just getting an Entries line; the local file is 1339 * correct. 1340 */ 1341 UPDATE_ENTRIES_CHECKIN, 1342 /* We are getting the file contents as well. */ 1343 UPDATE_ENTRIES_UPDATE, 1344 /* 1345 * We are getting a patch against the existing local file, not 1346 * an entire new file. 1347 */ 1348 UPDATE_ENTRIES_PATCH, 1349 /* 1350 * We are getting an RCS change text (diff -n output) against 1351 * the existing local file, not an entire new file. 1352 */ 1353 UPDATE_ENTRIES_RCS_DIFF 1354 } contents; 1355 1356 enum { 1357 /* We are replacing an existing file. */ 1358 UPDATE_ENTRIES_EXISTING, 1359 /* We are creating a new file. */ 1360 UPDATE_ENTRIES_NEW, 1361 /* We don't know whether it is existing or new. */ 1362 UPDATE_ENTRIES_EXISTING_OR_NEW 1363 } existp; 1364 1365 /* 1366 * String to put in the timestamp field or NULL to use the timestamp 1367 * of the file. 1368 */ 1369 char *timestamp; 1370 }; 1371 1372 1373 1374 /* Update the Entries line for this file. */ 1375 static void 1376 update_entries (void *data_arg, List *ent_list, const char *short_pathname, 1377 const char *filename) 1378 { 1379 char *entries_line; 1380 struct update_entries_data *data = data_arg; 1381 1382 char *cp; 1383 char *user; 1384 char *vn; 1385 /* Timestamp field. Always empty according to the protocol. */ 1386 char *ts; 1387 char *options = NULL; 1388 char *tag = NULL; 1389 char *date = NULL; 1390 char *tag_or_date; 1391 char *scratch_entries = NULL; 1392 int bin; 1393 1394 #ifdef UTIME_EXPECTS_WRITABLE 1395 int change_it_back = 0; 1396 #endif 1397 1398 read_line (&entries_line); 1399 1400 /* 1401 * Parse the entries line. 1402 */ 1403 scratch_entries = xstrdup (entries_line); 1404 1405 if (scratch_entries[0] != '/') 1406 error (1, 0, "bad entries line `%s' from server", entries_line); 1407 user = scratch_entries + 1; 1408 if (!(cp = strchr (user, '/'))) 1409 error (1, 0, "bad entries line `%s' from server", entries_line); 1410 *cp++ = '\0'; 1411 vn = cp; 1412 if (!(cp = strchr (vn, '/'))) 1413 error (1, 0, "bad entries line `%s' from server", entries_line); 1414 *cp++ = '\0'; 1415 1416 ts = cp; 1417 if (!(cp = strchr (ts, '/'))) 1418 error (1, 0, "bad entries line `%s' from server", entries_line); 1419 *cp++ = '\0'; 1420 options = cp; 1421 if (!(cp = strchr (options, '/'))) 1422 error (1, 0, "bad entries line `%s' from server", entries_line); 1423 *cp++ = '\0'; 1424 tag_or_date = cp; 1425 1426 /* If a slash ends the tag_or_date, ignore everything after it. */ 1427 cp = strchr (tag_or_date, '/'); 1428 if (cp) 1429 *cp = '\0'; 1430 if (*tag_or_date == 'T') 1431 tag = tag_or_date + 1; 1432 else if (*tag_or_date == 'D') 1433 date = tag_or_date + 1; 1434 1435 /* Done parsing the entries line. */ 1436 1437 if (data->contents == UPDATE_ENTRIES_UPDATE 1438 || data->contents == UPDATE_ENTRIES_PATCH 1439 || data->contents == UPDATE_ENTRIES_RCS_DIFF) 1440 { 1441 char *size_string; 1442 char *mode_string; 1443 int size; 1444 char *buf; 1445 char *temp_filename; 1446 int use_gzip; 1447 int patch_failed; 1448 1449 read_line (&mode_string); 1450 1451 read_line (&size_string); 1452 if (size_string[0] == 'z') 1453 { 1454 use_gzip = 1; 1455 size = atoi (size_string+1); 1456 } 1457 else 1458 { 1459 use_gzip = 0; 1460 size = atoi (size_string); 1461 } 1462 free (size_string); 1463 1464 /* Note that checking this separately from writing the file is 1465 a race condition: if the existence or lack thereof of the 1466 file changes between now and the actual calls which 1467 operate on it, we lose. However (a) there are so many 1468 cases, I'm reluctant to try to fix them all, (b) in some 1469 cases the system might not even have a system call which 1470 does the right thing, and (c) it isn't clear this needs to 1471 work. */ 1472 if (data->existp == UPDATE_ENTRIES_EXISTING 1473 && !isfile (filename)) 1474 /* Emit a warning and update the file anyway. */ 1475 error (0, 0, "warning: %s unexpectedly disappeared", 1476 short_pathname); 1477 1478 if (data->existp == UPDATE_ENTRIES_NEW 1479 && isfile (filename)) 1480 { 1481 /* Emit a warning and refuse to update the file; we don't want 1482 to clobber a user's file. */ 1483 size_t nread; 1484 size_t toread; 1485 1486 /* size should be unsigned, but until we get around to fixing 1487 that, work around it. */ 1488 size_t usize; 1489 1490 char buf[8192]; 1491 1492 /* This error might be confusing; it isn't really clear to 1493 the user what to do about it. Keep in mind that it has 1494 several causes: (1) something/someone creates the file 1495 during the time that CVS is running, (2) the repository 1496 has two files whose names clash for the client because 1497 of case-insensitivity or similar causes, See 3 for 1498 additional notes. (3) a special case of this is that a 1499 file gets renamed for example from a.c to A.C. A 1500 "cvs update" on a case-insensitive client will get this 1501 error. In this case and in case 2, the filename 1502 (short_pathname) printed in the error message will likely _not_ 1503 have the same case as seen by the user in a directory listing. 1504 (4) the client has a file which the server doesn't know 1505 about (e.g. "? foo" file), and that name clashes with a file 1506 the server does know about, (5) classify.c will print the same 1507 message for other reasons. 1508 1509 I hope the above paragraph makes it clear that making this 1510 clearer is not a one-line fix. */ 1511 error (0, 0, "move away `%s'; it is in the way", short_pathname); 1512 if (updated_fname) 1513 { 1514 cvs_output ("C ", 0); 1515 cvs_output (updated_fname, 0); 1516 cvs_output ("\n", 1); 1517 } 1518 failure_exit = true; 1519 1520 discard_file_and_return: 1521 /* Now read and discard the file contents. */ 1522 usize = size; 1523 nread = 0; 1524 while (nread < usize) 1525 { 1526 toread = usize - nread; 1527 if (toread > sizeof buf) 1528 toread = sizeof buf; 1529 1530 nread += try_read_from_server (buf, toread); 1531 if (nread == usize) 1532 break; 1533 } 1534 1535 free (mode_string); 1536 free (scratch_entries); 1537 free (entries_line); 1538 1539 /* The Mode, Mod-time, and Checksum responses should not carry 1540 over to a subsequent Created (or whatever) response, even 1541 in the error case. */ 1542 if (stored_mode) 1543 { 1544 free (stored_mode); 1545 stored_mode = NULL; 1546 } 1547 stored_modtime_valid = 0; 1548 stored_checksum_valid = 0; 1549 1550 if (updated_fname) 1551 { 1552 free (updated_fname); 1553 updated_fname = NULL; 1554 } 1555 return; 1556 } 1557 1558 temp_filename = xmalloc (strlen (filename) + 80); 1559 #ifdef USE_VMS_FILENAMES 1560 /* A VMS rename of "blah.dat" to "foo" to implies a 1561 destination of "foo.dat" which is unfortinate for CVS */ 1562 sprintf (temp_filename, "%s_new_", filename); 1563 #else 1564 #ifdef _POSIX_NO_TRUNC 1565 sprintf (temp_filename, ".new.%.9s", filename); 1566 #else /* _POSIX_NO_TRUNC */ 1567 sprintf (temp_filename, ".new.%s", filename); 1568 #endif /* _POSIX_NO_TRUNC */ 1569 #endif /* USE_VMS_FILENAMES */ 1570 1571 buf = xmalloc (size); 1572 1573 /* Some systems, like OS/2 and Windows NT, end lines with CRLF 1574 instead of just LF. Format translation is done in the C 1575 library I/O funtions. Here we tell them whether or not to 1576 convert -- if this file is marked "binary" with the RCS -kb 1577 flag, then we don't want to convert, else we do (because 1578 CVS assumes text files by default). */ 1579 1580 if (options) 1581 bin = !strcmp (options, "-kb"); 1582 else 1583 bin = 0; 1584 1585 if (data->contents == UPDATE_ENTRIES_RCS_DIFF) 1586 { 1587 /* This is an RCS change text. We just hold the change 1588 text in memory. */ 1589 1590 if (use_gzip) 1591 error (1, 0, 1592 "server error: gzip invalid with RCS change text"); 1593 1594 read_from_server (buf, size); 1595 } 1596 else 1597 { 1598 int fd; 1599 1600 fd = CVS_OPEN (temp_filename, 1601 (O_WRONLY | O_CREAT | O_TRUNC 1602 | (bin ? OPEN_BINARY : 0)), 1603 0777); 1604 1605 if (fd < 0) 1606 { 1607 /* I can see a case for making this a fatal error; for 1608 a condition like disk full or network unreachable 1609 (for a file server), carrying on and giving an 1610 error on each file seems unnecessary. But if it is 1611 a permission problem, or some such, then it is 1612 entirely possible that future files will not have 1613 the same problem. */ 1614 error (0, errno, "cannot write %s", short_pathname); 1615 free (temp_filename); 1616 free (buf); 1617 goto discard_file_and_return; 1618 } 1619 1620 if (size > 0) 1621 { 1622 read_from_server (buf, size); 1623 1624 if (use_gzip) 1625 { 1626 if (gunzip_and_write (fd, short_pathname, 1627 (unsigned char *) buf, size)) 1628 error (1, 0, "aborting due to compression error"); 1629 } 1630 else if (write (fd, buf, size) != size) 1631 error (1, errno, "writing %s", short_pathname); 1632 } 1633 1634 if (close (fd) < 0) 1635 error (1, errno, "writing %s", short_pathname); 1636 } 1637 1638 /* This is after we have read the file from the net (a change 1639 from previous versions, where the server would send us 1640 "M U foo.c" before Update-existing or whatever), but before 1641 we finish writing the file (arguably a bug). The timing 1642 affects a user who wants status info about how far we have 1643 gotten, and also affects whether "U foo.c" appears in addition 1644 to various error messages. */ 1645 if (updated_fname) 1646 { 1647 cvs_output ("U ", 0); 1648 cvs_output (updated_fname, 0); 1649 cvs_output ("\n", 1); 1650 free (updated_fname); 1651 updated_fname = 0; 1652 } 1653 1654 patch_failed = 0; 1655 1656 if (data->contents == UPDATE_ENTRIES_UPDATE) 1657 { 1658 rename_file (temp_filename, filename); 1659 } 1660 else if (data->contents == UPDATE_ENTRIES_PATCH) 1661 { 1662 /* You might think we could just leave Patched out of 1663 Valid-responses and not get this response. However, if 1664 memory serves, the CVS 1.9 server bases this on -u 1665 (update-patches), and there is no way for us to send -u 1666 or not based on whether the server supports "Rcs-diff". 1667 1668 Fall back to transmitting entire files. */ 1669 patch_failed = 1; 1670 } 1671 else 1672 { 1673 char *filebuf; 1674 size_t filebufsize; 1675 size_t nread; 1676 char *patchedbuf; 1677 size_t patchedlen; 1678 1679 /* Handle UPDATE_ENTRIES_RCS_DIFF. */ 1680 1681 if (!isfile (filename)) 1682 error (1, 0, "patch original file %s does not exist", 1683 short_pathname); 1684 filebuf = NULL; 1685 filebufsize = 0; 1686 nread = 0; 1687 1688 get_file (filename, short_pathname, bin ? FOPEN_BINARY_READ : "r", 1689 &filebuf, &filebufsize, &nread); 1690 /* At this point the contents of the existing file are in 1691 FILEBUF, and the length of the contents is in NREAD. 1692 The contents of the patch from the network are in BUF, 1693 and the length of the patch is in SIZE. */ 1694 1695 if (! rcs_change_text (short_pathname, filebuf, nread, buf, size, 1696 &patchedbuf, &patchedlen)) 1697 patch_failed = 1; 1698 else 1699 { 1700 if (stored_checksum_valid) 1701 { 1702 unsigned char checksum[16]; 1703 1704 /* We have a checksum. Check it before writing 1705 the file out, so that we don't have to read it 1706 back in again. */ 1707 md5_buffer (patchedbuf, patchedlen, checksum); 1708 if (memcmp (checksum, stored_checksum, 16) != 0) 1709 { 1710 error (0, 0, 1711 "checksum failure after patch to %s; will refetch", 1712 short_pathname); 1713 1714 patch_failed = 1; 1715 } 1716 1717 stored_checksum_valid = 0; 1718 } 1719 1720 if (! patch_failed) 1721 { 1722 FILE *e; 1723 1724 e = xfopen (temp_filename, 1725 bin ? FOPEN_BINARY_WRITE : "w"); 1726 if (fwrite (patchedbuf, sizeof *patchedbuf, patchedlen, e) 1727 != patchedlen) 1728 error (1, errno, "cannot write %s", temp_filename); 1729 if (fclose (e) == EOF) 1730 error (1, errno, "cannot close %s", temp_filename); 1731 rename_file (temp_filename, filename); 1732 } 1733 1734 free (patchedbuf); 1735 } 1736 1737 free (filebuf); 1738 } 1739 1740 free (temp_filename); 1741 1742 if (stored_checksum_valid && ! patch_failed) 1743 { 1744 FILE *e; 1745 struct md5_ctx context; 1746 unsigned char buf[8192]; 1747 unsigned len; 1748 unsigned char checksum[16]; 1749 1750 /* 1751 * Compute the MD5 checksum. This will normally only be 1752 * used when receiving a patch, so we always compute it 1753 * here on the final file, rather than on the received 1754 * data. 1755 * 1756 * Note that if the file is a text file, we should read it 1757 * here using text mode, so its lines will be terminated the same 1758 * way they were transmitted. 1759 */ 1760 e = CVS_FOPEN (filename, "r"); 1761 if (!e) 1762 error (1, errno, "could not open %s", short_pathname); 1763 1764 md5_init_ctx (&context); 1765 while ((len = fread (buf, 1, sizeof buf, e)) != 0) 1766 md5_process_bytes (buf, len, &context); 1767 if (ferror (e)) 1768 error (1, errno, "could not read %s", short_pathname); 1769 md5_finish_ctx (&context, checksum); 1770 1771 fclose (e); 1772 1773 stored_checksum_valid = 0; 1774 1775 if (memcmp (checksum, stored_checksum, 16) != 0) 1776 { 1777 if (data->contents != UPDATE_ENTRIES_PATCH) 1778 error (1, 0, "checksum failure on %s", 1779 short_pathname); 1780 1781 error (0, 0, 1782 "checksum failure after patch to %s; will refetch", 1783 short_pathname); 1784 1785 patch_failed = 1; 1786 } 1787 } 1788 1789 if (patch_failed) 1790 { 1791 /* Save this file to retrieve later. */ 1792 failed_patches = xnrealloc (failed_patches, 1793 failed_patches_count + 1, 1794 sizeof (char *)); 1795 failed_patches[failed_patches_count] = xstrdup (short_pathname); 1796 ++failed_patches_count; 1797 1798 stored_checksum_valid = 0; 1799 1800 free (mode_string); 1801 free (buf); 1802 free (scratch_entries); 1803 free (entries_line); 1804 1805 return; 1806 } 1807 1808 { 1809 int status = change_mode (filename, mode_string, 1); 1810 if (status != 0) 1811 error (0, status, "cannot change mode of %s", short_pathname); 1812 } 1813 1814 free (mode_string); 1815 free (buf); 1816 } 1817 1818 if (stored_mode) 1819 { 1820 change_mode (filename, stored_mode, 1); 1821 free (stored_mode); 1822 stored_mode = NULL; 1823 } 1824 1825 if (stored_modtime_valid) 1826 { 1827 struct utimbuf t; 1828 1829 memset (&t, 0, sizeof (t)); 1830 t.modtime = stored_modtime; 1831 (void) time (&t.actime); 1832 1833 #ifdef UTIME_EXPECTS_WRITABLE 1834 if (!iswritable (filename)) 1835 { 1836 xchmod (filename, 1); 1837 change_it_back = 1; 1838 } 1839 #endif /* UTIME_EXPECTS_WRITABLE */ 1840 1841 if (utime (filename, &t) < 0) 1842 error (0, errno, "cannot set time on %s", filename); 1843 1844 #ifdef UTIME_EXPECTS_WRITABLE 1845 if (change_it_back) 1846 { 1847 xchmod (filename, 0); 1848 change_it_back = 0; 1849 } 1850 #endif /* UTIME_EXPECTS_WRITABLE */ 1851 1852 stored_modtime_valid = 0; 1853 } 1854 1855 /* 1856 * Process the entries line. Do this after we've written the file, 1857 * since we need the timestamp. 1858 */ 1859 if (strcmp (cvs_cmd_name, "export")) 1860 { 1861 char *local_timestamp; 1862 char *file_timestamp; 1863 1864 (void) time (&last_register_time); 1865 1866 local_timestamp = data->timestamp; 1867 if (!local_timestamp || ts[0] == '+') 1868 file_timestamp = time_stamp (filename); 1869 else 1870 file_timestamp = NULL; 1871 1872 /* 1873 * These special version numbers signify that it is not up to 1874 * date. Create a dummy timestamp which will never compare 1875 * equal to the timestamp of the file. 1876 */ 1877 if (vn[0] == '\0' || !strcmp (vn, "0") || vn[0] == '-') 1878 local_timestamp = "dummy timestamp"; 1879 else if (!local_timestamp) 1880 { 1881 local_timestamp = file_timestamp; 1882 1883 /* Checking for cvs_cmd_name of "commit" doesn't seem like 1884 the cleanest way to handle this, but it seem to roughly 1885 parallel what the :local: code which calls 1886 mark_up_to_date ends up amounting to. Some day, should 1887 think more about what the Checked-in response means 1888 vis-a-vis both Entries and Base and clarify 1889 cvsclient.texi accordingly. */ 1890 1891 if (!strcmp (cvs_cmd_name, "commit")) 1892 mark_up_to_date (filename); 1893 } 1894 1895 Register (ent_list, filename, vn, local_timestamp, 1896 options, tag, date, ts[0] == '+' ? file_timestamp : NULL); 1897 1898 if (file_timestamp) 1899 free (file_timestamp); 1900 1901 } 1902 free (scratch_entries); 1903 free (entries_line); 1904 } 1905 1906 1907 1908 static void 1909 handle_checked_in (char *args, size_t len) 1910 { 1911 struct update_entries_data dat; 1912 dat.contents = UPDATE_ENTRIES_CHECKIN; 1913 dat.existp = UPDATE_ENTRIES_EXISTING_OR_NEW; 1914 dat.timestamp = NULL; 1915 call_in_directory (args, update_entries, &dat); 1916 } 1917 1918 1919 1920 static void 1921 handle_new_entry (char *args, size_t len) 1922 { 1923 struct update_entries_data dat; 1924 dat.contents = UPDATE_ENTRIES_CHECKIN; 1925 dat.existp = UPDATE_ENTRIES_EXISTING_OR_NEW; 1926 dat.timestamp = "dummy timestamp from new-entry"; 1927 call_in_directory (args, update_entries, &dat); 1928 } 1929 1930 1931 1932 static void 1933 handle_updated (char *args, size_t len) 1934 { 1935 struct update_entries_data dat; 1936 dat.contents = UPDATE_ENTRIES_UPDATE; 1937 dat.existp = UPDATE_ENTRIES_EXISTING_OR_NEW; 1938 dat.timestamp = NULL; 1939 call_in_directory (args, update_entries, &dat); 1940 } 1941 1942 1943 1944 static void 1945 handle_created (char *args, size_t len) 1946 { 1947 struct update_entries_data dat; 1948 dat.contents = UPDATE_ENTRIES_UPDATE; 1949 dat.existp = UPDATE_ENTRIES_NEW; 1950 dat.timestamp = NULL; 1951 call_in_directory (args, update_entries, &dat); 1952 } 1953 1954 1955 1956 static void 1957 handle_update_existing (char *args, size_t len) 1958 { 1959 struct update_entries_data dat; 1960 dat.contents = UPDATE_ENTRIES_UPDATE; 1961 dat.existp = UPDATE_ENTRIES_EXISTING; 1962 dat.timestamp = NULL; 1963 call_in_directory (args, update_entries, &dat); 1964 } 1965 1966 1967 1968 static void 1969 handle_merged (char *args, size_t len) 1970 { 1971 struct update_entries_data dat; 1972 dat.contents = UPDATE_ENTRIES_UPDATE; 1973 /* Think this could be UPDATE_ENTRIES_EXISTING, but just in case... */ 1974 dat.existp = UPDATE_ENTRIES_EXISTING_OR_NEW; 1975 dat.timestamp = "Result of merge"; 1976 call_in_directory (args, update_entries, &dat); 1977 } 1978 1979 1980 1981 static void 1982 handle_patched (char *args, size_t len) 1983 { 1984 struct update_entries_data dat; 1985 dat.contents = UPDATE_ENTRIES_PATCH; 1986 /* Think this could be UPDATE_ENTRIES_EXISTING, but just in case... */ 1987 dat.existp = UPDATE_ENTRIES_EXISTING_OR_NEW; 1988 dat.timestamp = NULL; 1989 call_in_directory (args, update_entries, &dat); 1990 } 1991 1992 1993 1994 static void 1995 handle_rcs_diff (char *args, size_t len) 1996 { 1997 struct update_entries_data dat; 1998 dat.contents = UPDATE_ENTRIES_RCS_DIFF; 1999 /* Think this could be UPDATE_ENTRIES_EXISTING, but just in case... */ 2000 dat.existp = UPDATE_ENTRIES_EXISTING_OR_NEW; 2001 dat.timestamp = NULL; 2002 call_in_directory (args, update_entries, &dat); 2003 } 2004 2005 2006 2007 static void 2008 remove_entry (void *data, List *ent_list, const char *short_pathname, 2009 const char *filename) 2010 { 2011 Scratch_Entry (ent_list, filename); 2012 } 2013 2014 2015 2016 static void 2017 handle_remove_entry (char *args, size_t len) 2018 { 2019 call_in_directory (args, remove_entry, NULL); 2020 } 2021 2022 2023 2024 static void 2025 remove_entry_and_file (void *data, List *ent_list, const char *short_pathname, 2026 const char *filename) 2027 { 2028 Scratch_Entry (ent_list, filename); 2029 /* Note that we don't ignore existence_error's here. The server 2030 should be sending Remove-entry rather than Removed in cases 2031 where the file does not exist. And if the user removes the 2032 file halfway through a cvs command, we should be printing an 2033 error. */ 2034 if (unlink_file (filename) < 0) 2035 error (0, errno, "unable to remove %s", short_pathname); 2036 } 2037 2038 2039 2040 static void 2041 handle_removed (char *args, size_t len) 2042 { 2043 call_in_directory (args, remove_entry_and_file, NULL); 2044 } 2045 2046 2047 2048 /* Is this the top level (directory containing CVSROOT)? */ 2049 static int 2050 is_cvsroot_level (char *pathname) 2051 { 2052 if (strcmp (toplevel_repos, current_parsed_root->directory)) 2053 return 0; 2054 2055 return !strchr (pathname, '/'); 2056 } 2057 2058 2059 2060 static void 2061 set_static (void *data, List *ent_list, const char *short_pathname, 2062 const char *filename) 2063 { 2064 FILE *fp; 2065 fp = xfopen (CVSADM_ENTSTAT, "w+"); 2066 if (fclose (fp) == EOF) 2067 error (1, errno, "cannot close %s", CVSADM_ENTSTAT); 2068 } 2069 2070 2071 2072 static void 2073 handle_set_static_directory (char *args, size_t len) 2074 { 2075 if (!strcmp (cvs_cmd_name, "export")) 2076 { 2077 /* Swallow the repository. */ 2078 read_line (NULL); 2079 return; 2080 } 2081 call_in_directory (args, set_static, NULL); 2082 } 2083 2084 2085 2086 static void 2087 clear_static (void *data, List *ent_list, const char *short_pathname, 2088 const char *filename) 2089 { 2090 if (unlink_file (CVSADM_ENTSTAT) < 0 && ! existence_error (errno)) 2091 error (1, errno, "cannot remove file %s", CVSADM_ENTSTAT); 2092 } 2093 2094 2095 2096 static void 2097 handle_clear_static_directory (char *pathname, size_t len) 2098 { 2099 if (!strcmp (cvs_cmd_name, "export")) 2100 { 2101 /* Swallow the repository. */ 2102 read_line (NULL); 2103 return; 2104 } 2105 2106 if (is_cvsroot_level (pathname)) 2107 { 2108 /* 2109 * Top level (directory containing CVSROOT). This seems to normally 2110 * lack a CVS directory, so don't try to create files in it. 2111 */ 2112 return; 2113 } 2114 call_in_directory (pathname, clear_static, NULL); 2115 } 2116 2117 2118 2119 static void 2120 set_sticky (void *data, List *ent_list, const char *short_pathname, 2121 const char *filename) 2122 { 2123 char *tagspec; 2124 FILE *f; 2125 2126 read_line (&tagspec); 2127 2128 /* FIXME-update-dir: error messages should include the directory. */ 2129 f = CVS_FOPEN (CVSADM_TAG, "w+"); 2130 if (!f) 2131 { 2132 /* Making this non-fatal is a bit of a kludge (see dirs2 2133 in testsuite). A better solution would be to avoid having 2134 the server tell us about a directory we shouldn't be doing 2135 anything with anyway (e.g. by handling directory 2136 addition/removal better). */ 2137 error (0, errno, "cannot open %s", CVSADM_TAG); 2138 free (tagspec); 2139 return; 2140 } 2141 if (fprintf (f, "%s\n", tagspec) < 0) 2142 error (1, errno, "writing %s", CVSADM_TAG); 2143 if (fclose (f) == EOF) 2144 error (1, errno, "closing %s", CVSADM_TAG); 2145 free (tagspec); 2146 } 2147 2148 2149 2150 static void 2151 handle_set_sticky (char *pathname, size_t len) 2152 { 2153 if (!strcmp (cvs_cmd_name, "export")) 2154 { 2155 /* Swallow the repository. */ 2156 read_line (NULL); 2157 /* Swallow the tag line. */ 2158 read_line (NULL); 2159 return; 2160 } 2161 if (is_cvsroot_level (pathname)) 2162 { 2163 /* 2164 * Top level (directory containing CVSROOT). This seems to normally 2165 * lack a CVS directory, so don't try to create files in it. 2166 */ 2167 2168 /* Swallow the repository. */ 2169 read_line (NULL); 2170 /* Swallow the tag line. */ 2171 read_line (NULL); 2172 return; 2173 } 2174 2175 call_in_directory (pathname, set_sticky, NULL); 2176 } 2177 2178 2179 2180 static void 2181 clear_sticky (void *data, List *ent_list, const char *short_pathname, 2182 const char *filename) 2183 { 2184 if (unlink_file (CVSADM_TAG) < 0 && ! existence_error (errno)) 2185 error (1, errno, "cannot remove %s", CVSADM_TAG); 2186 } 2187 2188 2189 2190 static void 2191 handle_clear_sticky (char *pathname, size_t len) 2192 { 2193 if (!strcmp (cvs_cmd_name, "export")) 2194 { 2195 /* Swallow the repository. */ 2196 read_line (NULL); 2197 return; 2198 } 2199 2200 if (is_cvsroot_level (pathname)) 2201 { 2202 /* 2203 * Top level (directory containing CVSROOT). This seems to normally 2204 * lack a CVS directory, so don't try to create files in it. 2205 */ 2206 return; 2207 } 2208 2209 call_in_directory (pathname, clear_sticky, NULL); 2210 } 2211 2212 2213 2214 /* Handle the client-side support for a successful edit. 2215 */ 2216 static void 2217 handle_edit_file (char *pathname, size_t len) 2218 { 2219 call_in_directory (pathname, edit_file, NULL); 2220 } 2221 2222 2223 2224 static void 2225 template (void *data, List *ent_list, const char *short_pathname, 2226 const char *filename) 2227 { 2228 char *buf = Xasprintf ("%s/%s", short_pathname, CVSADM_TEMPLATE); 2229 read_counted_file (CVSADM_TEMPLATE, buf); 2230 free (buf); 2231 } 2232 2233 2234 2235 static void 2236 handle_template (char *pathname, size_t len) 2237 { 2238 call_in_directory (pathname, template, NULL); 2239 } 2240 2241 2242 2243 static void 2244 clear_template (void *data, List *ent_list, const char *short_pathname, 2245 const char *filename) 2246 { 2247 if (unlink_file (CVSADM_TEMPLATE) < 0 && ! existence_error (errno)) 2248 error (1, errno, "cannot remove %s", CVSADM_TEMPLATE); 2249 } 2250 2251 2252 2253 static void 2254 handle_clear_template (char *pathname, size_t len) 2255 { 2256 call_in_directory (pathname, clear_template, NULL); 2257 } 2258 2259 2260 2261 struct save_dir { 2262 char *dir; 2263 struct save_dir *next; 2264 }; 2265 2266 struct save_dir *prune_candidates; 2267 2268 static void 2269 add_prune_candidate (const char *dir) 2270 { 2271 struct save_dir *p; 2272 2273 if ((dir[0] == '.' && dir[1] == '\0') 2274 || (prune_candidates && !strcmp (dir, prune_candidates->dir))) 2275 return; 2276 p = xmalloc (sizeof (struct save_dir)); 2277 p->dir = xstrdup (dir); 2278 p->next = prune_candidates; 2279 prune_candidates = p; 2280 } 2281 2282 2283 2284 static void 2285 process_prune_candidates (void) 2286 { 2287 struct save_dir *p; 2288 struct save_dir *q; 2289 2290 if (toplevel_wd) 2291 { 2292 if (CVS_CHDIR (toplevel_wd) < 0) 2293 error (1, errno, "could not chdir to %s", toplevel_wd); 2294 } 2295 for (p = prune_candidates; p; ) 2296 { 2297 if (isemptydir (p->dir, 1)) 2298 { 2299 char *b; 2300 2301 if (unlink_file_dir (p->dir) < 0) 2302 error (0, errno, "cannot remove %s", p->dir); 2303 b = strrchr (p->dir, '/'); 2304 if (!b) 2305 Subdir_Deregister (NULL, NULL, p->dir); 2306 else 2307 { 2308 *b = '\0'; 2309 Subdir_Deregister (NULL, p->dir, b + 1); 2310 } 2311 } 2312 free (p->dir); 2313 q = p->next; 2314 free (p); 2315 p = q; 2316 } 2317 prune_candidates = NULL; 2318 } 2319 2320 2321 2322 /* Send a Repository line. */ 2323 static char *last_repos; 2324 static char *last_update_dir; 2325 static void 2326 send_repository (const char *dir, const char *repos, const char *update_dir) 2327 { 2328 char *adm_name; 2329 2330 /* FIXME: this is probably not the best place to check; I wish I 2331 * knew where in here's callers to really trap this bug. To 2332 * reproduce the bug, just do this: 2333 * 2334 * mkdir junk 2335 * cd junk 2336 * cvs -d some_repos update foo 2337 * 2338 * Poof, CVS seg faults and dies! It's because it's trying to 2339 * send a NULL string to the server but dies in send_to_server. 2340 * That string was supposed to be the repository, but it doesn't 2341 * get set because there's no CVSADM dir, and somehow it's not 2342 * getting set from the -d argument either... ? 2343 */ 2344 if (!repos) 2345 { 2346 /* Lame error. I want a real fix but can't stay up to track 2347 this down right now. */ 2348 error (1, 0, "no repository"); 2349 } 2350 2351 if (!update_dir || update_dir[0] == '\0') 2352 update_dir = "."; 2353 2354 if (last_repos && !strcmp (repos, last_repos) 2355 && last_update_dir && !strcmp (update_dir, last_update_dir)) 2356 /* We've already sent it. */ 2357 return; 2358 2359 if (client_prune_dirs) 2360 add_prune_candidate (update_dir); 2361 2362 /* Add a directory name to the list of those sent to the 2363 server. */ 2364 if (update_dir && *update_dir != '\0' && strcmp (update_dir, ".") 2365 && !findnode (dirs_sent_to_server, update_dir)) 2366 { 2367 Node *n; 2368 n = getnode (); 2369 n->type = NT_UNKNOWN; 2370 n->key = xstrdup (update_dir); 2371 n->data = NULL; 2372 2373 if (addnode (dirs_sent_to_server, n)) 2374 error (1, 0, "cannot add directory %s to list", n->key); 2375 } 2376 2377 /* 80 is large enough for any of CVSADM_*. */ 2378 adm_name = xmalloc (strlen (dir) + 80); 2379 2380 send_to_server ("Directory ", 0); 2381 { 2382 /* Send the directory name. I know that this 2383 sort of duplicates code elsewhere, but each 2384 case seems slightly different... */ 2385 char buf[1]; 2386 const char *p = update_dir; 2387 while (*p != '\0') 2388 { 2389 assert (*p != '\012'); 2390 if (ISSLASH (*p)) 2391 { 2392 buf[0] = '/'; 2393 send_to_server (buf, 1); 2394 } 2395 else 2396 { 2397 buf[0] = *p; 2398 send_to_server (buf, 1); 2399 } 2400 ++p; 2401 } 2402 } 2403 send_to_server ("\012", 1); 2404 if (supported_request ("Relative-directory")) 2405 { 2406 const char *short_repos = Short_Repository (repos); 2407 send_to_server (short_repos, 0); 2408 } 2409 else 2410 send_to_server (repos, 0); 2411 send_to_server ("\012", 1); 2412 2413 if (supported_request ("Static-directory")) 2414 { 2415 adm_name[0] = '\0'; 2416 if (dir[0] != '\0') 2417 { 2418 strcat (adm_name, dir); 2419 strcat (adm_name, "/"); 2420 } 2421 strcat (adm_name, CVSADM_ENTSTAT); 2422 if (isreadable (adm_name)) 2423 { 2424 send_to_server ("Static-directory\012", 0); 2425 } 2426 } 2427 if (supported_request ("Sticky")) 2428 { 2429 FILE *f; 2430 if (dir[0] == '\0') 2431 strcpy (adm_name, CVSADM_TAG); 2432 else 2433 sprintf (adm_name, "%s/%s", dir, CVSADM_TAG); 2434 2435 f = CVS_FOPEN (adm_name, "r"); 2436 if (!f) 2437 { 2438 if (! existence_error (errno)) 2439 error (1, errno, "reading %s", adm_name); 2440 } 2441 else 2442 { 2443 char line[80]; 2444 char *nl = NULL; 2445 send_to_server ("Sticky ", 0); 2446 while (fgets (line, sizeof (line), f)) 2447 { 2448 send_to_server (line, 0); 2449 nl = strchr (line, '\n'); 2450 if (nl) 2451 break; 2452 } 2453 if (!nl) 2454 send_to_server ("\012", 1); 2455 if (fclose (f) == EOF) 2456 error (0, errno, "closing %s", adm_name); 2457 } 2458 } 2459 free (adm_name); 2460 if (last_repos) free (last_repos); 2461 if (last_update_dir) free (last_update_dir); 2462 last_repos = xstrdup (repos); 2463 last_update_dir = xstrdup (update_dir); 2464 } 2465 2466 2467 2468 /* Send a Repository line and set toplevel_repos. */ 2469 void 2470 send_a_repository (const char *dir, const char *repository, 2471 const char *update_dir_in) 2472 { 2473 char *update_dir = xstrdup (update_dir_in); 2474 2475 if (!toplevel_repos && repository) 2476 { 2477 if (update_dir[0] == '\0' 2478 || (update_dir[0] == '.' && update_dir[1] == '\0')) 2479 toplevel_repos = xstrdup (repository); 2480 else 2481 { 2482 /* 2483 * Get the repository from a CVS/Repository file if update_dir 2484 * is absolute. This is not correct in general, because 2485 * the CVS/Repository file might not be the top-level one. 2486 * This is for cases like "cvs update /foo/bar" (I'm not 2487 * sure it matters what toplevel_repos we get, but it does 2488 * matter that we don't hit the "internal error" code below). 2489 */ 2490 if (update_dir[0] == '/') 2491 toplevel_repos = Name_Repository (update_dir, update_dir); 2492 else 2493 { 2494 /* 2495 * Guess the repository of that directory by looking at a 2496 * subdirectory and removing as many pathname components 2497 * as are in update_dir. I think that will always (or at 2498 * least almost always) be 1. 2499 * 2500 * So this deals with directories which have been 2501 * renamed, though it doesn't necessarily deal with 2502 * directories which have been put inside other 2503 * directories (and cvs invoked on the containing 2504 * directory). I'm not sure the latter case needs to 2505 * work. 2506 * 2507 * 21 Aug 1998: Well, Mr. Above-Comment-Writer, it 2508 * does need to work after all. When we are using the 2509 * client in a multi-cvsroot environment, it will be 2510 * fairly common that we have the above case (e.g., 2511 * cwd checked out from one repository but 2512 * subdirectory checked out from another). We can't 2513 * assume that by walking up a directory in our wd we 2514 * necessarily walk up a directory in the repository. 2515 */ 2516 /* 2517 * This gets toplevel_repos wrong for "cvs update ../foo" 2518 * but I'm not sure toplevel_repos matters in that case. 2519 */ 2520 2521 int repository_len, update_dir_len; 2522 2523 strip_trailing_slashes (update_dir); 2524 2525 repository_len = strlen (repository); 2526 update_dir_len = strlen (update_dir); 2527 2528 /* Try to remove the path components in UPDATE_DIR 2529 from REPOSITORY. If the path elements don't exist 2530 in REPOSITORY, or the removal of those path 2531 elements mean that we "step above" 2532 current_parsed_root->directory, set toplevel_repos to 2533 current_parsed_root->directory. */ 2534 if (repository_len > update_dir_len 2535 && !strcmp (repository + repository_len - update_dir_len, 2536 update_dir) 2537 /* TOPLEVEL_REPOS shouldn't be above current_parsed_root->directory */ 2538 && ((size_t)(repository_len - update_dir_len) 2539 > strlen (current_parsed_root->directory))) 2540 { 2541 /* The repository name contains UPDATE_DIR. Set 2542 toplevel_repos to the repository name without 2543 UPDATE_DIR. */ 2544 2545 toplevel_repos = xmalloc (repository_len - update_dir_len); 2546 /* Note that we don't copy the trailing '/'. */ 2547 strncpy (toplevel_repos, repository, 2548 repository_len - update_dir_len - 1); 2549 toplevel_repos[repository_len - update_dir_len - 1] = '\0'; 2550 } 2551 else 2552 { 2553 toplevel_repos = xstrdup (current_parsed_root->directory); 2554 } 2555 } 2556 } 2557 } 2558 2559 send_repository (dir, repository, update_dir); 2560 free (update_dir); 2561 } 2562 2563 2564 2565 static void 2566 notified_a_file (void *data, List *ent_list, const char *short_pathname, 2567 const char *filename) 2568 { 2569 FILE *fp; 2570 FILE *newf; 2571 size_t line_len = 8192; 2572 char *line = xmalloc (line_len); 2573 char *cp; 2574 int nread; 2575 int nwritten; 2576 char *p; 2577 2578 fp = xfopen (CVSADM_NOTIFY, "r"); 2579 if (getline (&line, &line_len, fp) < 0) 2580 { 2581 if (feof (fp)) 2582 error (0, 0, "cannot read %s: end of file", CVSADM_NOTIFY); 2583 else 2584 error (0, errno, "cannot read %s", CVSADM_NOTIFY); 2585 goto error_exit; 2586 } 2587 cp = strchr (line, '\t'); 2588 if (!cp) 2589 { 2590 error (0, 0, "malformed %s file", CVSADM_NOTIFY); 2591 goto error_exit; 2592 } 2593 *cp = '\0'; 2594 if (strcmp (filename, line + 1)) 2595 error (0, 0, "protocol error: notified %s, expected %s", filename, 2596 line + 1); 2597 2598 if (getline (&line, &line_len, fp) < 0) 2599 { 2600 if (feof (fp)) 2601 { 2602 free (line); 2603 if (fclose (fp) < 0) 2604 error (0, errno, "cannot close %s", CVSADM_NOTIFY); 2605 if ( CVS_UNLINK (CVSADM_NOTIFY) < 0) 2606 error (0, errno, "cannot remove %s", CVSADM_NOTIFY); 2607 return; 2608 } 2609 else 2610 { 2611 error (0, errno, "cannot read %s", CVSADM_NOTIFY); 2612 goto error_exit; 2613 } 2614 } 2615 newf = xfopen (CVSADM_NOTIFYTMP, "w"); 2616 if (fputs (line, newf) < 0) 2617 { 2618 error (0, errno, "cannot write %s", CVSADM_NOTIFYTMP); 2619 goto error2; 2620 } 2621 while ((nread = fread (line, 1, line_len, fp)) > 0) 2622 { 2623 p = line; 2624 while ((nwritten = fwrite (p, sizeof *p, nread, newf)) > 0) 2625 { 2626 nread -= nwritten; 2627 p += nwritten; 2628 } 2629 if (ferror (newf)) 2630 { 2631 error (0, errno, "cannot write %s", CVSADM_NOTIFYTMP); 2632 goto error2; 2633 } 2634 } 2635 if (ferror (fp)) 2636 { 2637 error (0, errno, "cannot read %s", CVSADM_NOTIFY); 2638 goto error2; 2639 } 2640 if (fclose (newf) < 0) 2641 { 2642 error (0, errno, "cannot close %s", CVSADM_NOTIFYTMP); 2643 goto error_exit; 2644 } 2645 free (line); 2646 if (fclose (fp) < 0) 2647 { 2648 error (0, errno, "cannot close %s", CVSADM_NOTIFY); 2649 return; 2650 } 2651 2652 { 2653 /* In this case, we want rename_file() to ignore noexec. */ 2654 int saved_noexec = noexec; 2655 noexec = 0; 2656 rename_file (CVSADM_NOTIFYTMP, CVSADM_NOTIFY); 2657 noexec = saved_noexec; 2658 } 2659 2660 return; 2661 error2: 2662 (void)fclose (newf); 2663 error_exit: 2664 free (line); 2665 (void)fclose (fp); 2666 } 2667 2668 2669 2670 static void 2671 handle_notified (char *args, size_t len) 2672 { 2673 call_in_directory (args, notified_a_file, NULL); 2674 } 2675 2676 2677 2678 /* The "expanded" modules. */ 2679 static int modules_count; 2680 static int modules_allocated; 2681 static char **modules_vector; 2682 2683 static void 2684 handle_module_expansion (char *args, size_t len) 2685 { 2686 if (!modules_vector) 2687 { 2688 modules_allocated = 1; /* Small for testing */ 2689 modules_vector = xnmalloc (modules_allocated, 2690 sizeof (modules_vector[0])); 2691 } 2692 else if (modules_count >= modules_allocated) 2693 { 2694 modules_allocated *= 2; 2695 modules_vector = xnrealloc (modules_vector, 2696 modules_allocated, 2697 sizeof (modules_vector[0])); 2698 } 2699 modules_vector[modules_count] = xstrdup (args); 2700 ++modules_count; 2701 } 2702 2703 2704 2705 /* Original, not "expanded" modules. */ 2706 static int module_argc; 2707 static char **module_argv; 2708 2709 void 2710 client_expand_modules (int argc, char **argv, int local) 2711 { 2712 int errs; 2713 int i; 2714 2715 module_argc = argc; 2716 module_argv = xnmalloc (argc + 1, sizeof (module_argv[0])); 2717 for (i = 0; i < argc; ++i) 2718 module_argv[i] = xstrdup (argv[i]); 2719 module_argv[argc] = NULL; 2720 2721 for (i = 0; i < argc; ++i) 2722 send_arg (argv[i]); 2723 send_a_repository ("", current_parsed_root->directory, ""); 2724 2725 send_to_server ("expand-modules\012", 0); 2726 2727 errs = get_server_responses (); 2728 2729 if (last_repos) free (last_repos); 2730 last_repos = NULL; 2731 2732 if (last_update_dir) free (last_update_dir); 2733 last_update_dir = NULL; 2734 2735 if (errs) 2736 error (errs, 0, "cannot expand modules"); 2737 } 2738 2739 2740 2741 void 2742 client_send_expansions (int local, char *where, int build_dirs) 2743 { 2744 int i; 2745 char *argv[1]; 2746 2747 /* Send the original module names. The "expanded" module name might 2748 not be suitable as an argument to a co request (e.g. it might be 2749 the result of a -d argument in the modules file). It might be 2750 cleaner if we genuinely expanded module names, all the way to a 2751 local directory and repository, but that isn't the way it works 2752 now. */ 2753 send_file_names (module_argc, module_argv, 0); 2754 2755 for (i = 0; i < modules_count; ++i) 2756 { 2757 argv[0] = where ? where : modules_vector[i]; 2758 if (isfile (argv[0])) 2759 send_files (1, argv, local, 0, build_dirs ? SEND_BUILD_DIRS : 0); 2760 } 2761 send_a_repository ("", current_parsed_root->directory, ""); 2762 } 2763 2764 2765 2766 void 2767 client_nonexpanded_setup (void) 2768 { 2769 send_a_repository ("", current_parsed_root->directory, ""); 2770 } 2771 2772 2773 2774 /* Receive a cvswrappers line from the server; it must be a line 2775 containing an RCS option (e.g., "*.exe -k 'b'"). 2776 2777 Note that this doesn't try to handle -t/-f options (which are a 2778 whole separate issue which noone has thought much about, as far 2779 as I know). 2780 2781 We need to know the keyword expansion mode so we know whether to 2782 read the file in text or binary mode. */ 2783 static void 2784 handle_wrapper_rcs_option (char *args, size_t len) 2785 { 2786 char *p; 2787 2788 /* Enforce the notes in cvsclient.texi about how the response is not 2789 as free-form as it looks. */ 2790 p = strchr (args, ' '); 2791 if (!p) 2792 goto handle_error; 2793 if (*++p != '-' 2794 || *++p != 'k' 2795 || *++p != ' ' 2796 || *++p != '\'') 2797 goto handle_error; 2798 if (!strchr (p, '\'')) 2799 goto handle_error; 2800 2801 /* Add server-side cvswrappers line to our wrapper list. */ 2802 wrap_add (args, 0); 2803 return; 2804 handle_error: 2805 error (0, errno, "protocol error: ignoring invalid wrappers %s", args); 2806 } 2807 2808 2809 2810 2811 static void 2812 handle_m (char *args, size_t len) 2813 { 2814 /* In the case where stdout and stderr point to the same place, 2815 fflushing stderr will make output happen in the correct order. 2816 Often stderr will be line-buffered and this won't be needed, 2817 but not always (is that true? I think the comment is probably 2818 based on being confused between default buffering between 2819 stdout and stderr. But I'm not sure). */ 2820 fflush (stderr); 2821 fwrite (args, sizeof *args, len, stdout); 2822 putc ('\n', stdout); 2823 } 2824 2825 2826 2827 static void 2828 handle_mbinary (char *args, size_t len) 2829 { 2830 char *size_string; 2831 size_t size; 2832 size_t totalread; 2833 size_t nread; 2834 size_t toread; 2835 char buf[8192]; 2836 2837 /* See comment at handle_m about (non)flush of stderr. */ 2838 2839 /* Get the size. */ 2840 read_line (&size_string); 2841 size = atoi (size_string); 2842 free (size_string); 2843 2844 /* OK, now get all the data. The algorithm here is that we read 2845 as much as the network wants to give us in 2846 try_read_from_server, and then we output it all, and then 2847 repeat, until we get all the data. */ 2848 totalread = 0; 2849 while (totalread < size) 2850 { 2851 toread = size - totalread; 2852 if (toread > sizeof buf) 2853 toread = sizeof buf; 2854 2855 nread = try_read_from_server (buf, toread); 2856 cvs_output_binary (buf, nread); 2857 totalread += nread; 2858 } 2859 } 2860 2861 2862 2863 static void 2864 handle_e (char *args, size_t len) 2865 { 2866 /* In the case where stdout and stderr point to the same place, 2867 fflushing stdout will make output happen in the correct order. */ 2868 fflush (stdout); 2869 fwrite (args, sizeof *args, len, stderr); 2870 putc ('\n', stderr); 2871 } 2872 2873 2874 2875 /*ARGSUSED*/ 2876 static void 2877 handle_f (char *args, size_t len) 2878 { 2879 fflush (stderr); 2880 } 2881 2882 2883 2884 static void 2885 handle_mt (char *args, size_t len) 2886 { 2887 char *p; 2888 char *tag = args; 2889 char *text; 2890 2891 /* See comment at handle_m for more details. */ 2892 fflush (stderr); 2893 2894 p = strchr (args, ' '); 2895 if (!p) 2896 text = NULL; 2897 else 2898 { 2899 *p++ = '\0'; 2900 text = p; 2901 } 2902 2903 switch (tag[0]) 2904 { 2905 case '+': 2906 if (!strcmp (tag, "+updated")) 2907 updated_seen = 1; 2908 else if (!strcmp (tag, "+importmergecmd")) 2909 importmergecmd.seen = 1; 2910 break; 2911 case '-': 2912 if (!strcmp (tag, "-updated")) 2913 updated_seen = 0; 2914 else if (!strcmp (tag, "-importmergecmd")) 2915 { 2916 char buf[80]; 2917 2918 /* Now that we have gathered the information, we can 2919 output the suggested merge command. */ 2920 2921 if (importmergecmd.conflicts == 0 2922 || !importmergecmd.mergetag1 2923 || !importmergecmd.mergetag2 2924 || !importmergecmd.repository) 2925 { 2926 error (0, 0, 2927 "invalid server: incomplete importmergecmd tags"); 2928 break; 2929 } 2930 2931 if (importmergecmd.conflicts == -1) 2932 sprintf (buf, "\nNo conflicts created by this import.\n"); 2933 else 2934 sprintf (buf, "\n%d conflicts created by this import.\n", 2935 importmergecmd.conflicts); 2936 cvs_output (buf, 0); 2937 cvs_output ("Use the following command to help the merge:\n\n", 2938 0); 2939 cvs_output ("\t", 1); 2940 cvs_output (program_name, 0); 2941 if (CVSroot_cmdline) 2942 { 2943 cvs_output (" -d ", 0); 2944 cvs_output (CVSroot_cmdline, 0); 2945 } 2946 cvs_output (" checkout -j", 0); 2947 cvs_output (importmergecmd.mergetag1, 0); 2948 cvs_output (" -j", 0); 2949 cvs_output (importmergecmd.mergetag2, 0); 2950 cvs_output (" ", 1); 2951 cvs_output (importmergecmd.repository, 0); 2952 cvs_output ("\n\n", 0); 2953 2954 /* Clear the static variables so that everything is 2955 ready for any subsequent importmergecmd tag. */ 2956 importmergecmd.conflicts = 0; 2957 free (importmergecmd.mergetag1); 2958 importmergecmd.mergetag1 = NULL; 2959 free (importmergecmd.mergetag2); 2960 importmergecmd.mergetag2 = NULL; 2961 free (importmergecmd.repository); 2962 importmergecmd.repository = NULL; 2963 2964 importmergecmd.seen = 0; 2965 } 2966 break; 2967 default: 2968 if (updated_seen) 2969 { 2970 if (!strcmp (tag, "fname")) 2971 { 2972 if (updated_fname) 2973 { 2974 /* Output the previous message now. This can happen 2975 if there was no Update-existing or other such 2976 response, due to the -n global option. */ 2977 cvs_output ("U ", 0); 2978 cvs_output (updated_fname, 0); 2979 cvs_output ("\n", 1); 2980 free (updated_fname); 2981 } 2982 updated_fname = xstrdup (text); 2983 } 2984 /* Swallow all other tags. Either they are extraneous 2985 or they reflect future extensions that we can 2986 safely ignore. */ 2987 } 2988 else if (importmergecmd.seen) 2989 { 2990 if (!strcmp (tag, "conflicts")) 2991 { 2992 if (!strcmp (text, "No")) 2993 importmergecmd.conflicts = -1; 2994 else 2995 importmergecmd.conflicts = atoi (text); 2996 } 2997 else if (!strcmp (tag, "mergetag1")) 2998 importmergecmd.mergetag1 = xstrdup (text); 2999 else if (!strcmp (tag, "mergetag2")) 3000 importmergecmd.mergetag2 = xstrdup (text); 3001 else if (!strcmp (tag, "repository")) 3002 importmergecmd.repository = xstrdup (text); 3003 /* Swallow all other tags. Either they are text for 3004 which we are going to print our own version when we 3005 see -importmergecmd, or they are future extensions 3006 we can safely ignore. */ 3007 } 3008 else if (!strcmp (tag, "newline")) 3009 printf ("\n"); 3010 else if (!strcmp (tag, "date")) 3011 { 3012 char *date = format_date_alloc (text); 3013 printf ("%s", date); 3014 free (date); 3015 } 3016 else if (text) 3017 printf ("%s", text); 3018 } 3019 } 3020 3021 3022 3023 #endif /* CLIENT_SUPPORT */ 3024 #if defined(CLIENT_SUPPORT) || defined(SERVER_SUPPORT) 3025 3026 /* This table must be writeable if the server code is included. */ 3027 struct response responses[] = 3028 { 3029 #ifdef CLIENT_SUPPORT 3030 #define RSP_LINE(n, f, t, s) {n, f, t, s} 3031 #else /* ! CLIENT_SUPPORT */ 3032 #define RSP_LINE(n, f, t, s) {n, s} 3033 #endif /* CLIENT_SUPPORT */ 3034 3035 RSP_LINE("ok", handle_ok, response_type_ok, rs_essential), 3036 RSP_LINE("error", handle_error, response_type_error, rs_essential), 3037 RSP_LINE("Valid-requests", handle_valid_requests, response_type_normal, 3038 rs_essential), 3039 RSP_LINE("Force-gzip", handle_force_gzip, response_type_normal, 3040 rs_optional), 3041 RSP_LINE("Referrer", handle_referrer, response_type_normal, rs_optional), 3042 RSP_LINE("Redirect", handle_redirect, response_type_redirect, rs_optional), 3043 RSP_LINE("Checked-in", handle_checked_in, response_type_normal, 3044 rs_essential), 3045 RSP_LINE("New-entry", handle_new_entry, response_type_normal, rs_optional), 3046 RSP_LINE("Checksum", handle_checksum, response_type_normal, rs_optional), 3047 RSP_LINE("Copy-file", handle_copy_file, response_type_normal, rs_optional), 3048 RSP_LINE("Updated", handle_updated, response_type_normal, rs_essential), 3049 RSP_LINE("Created", handle_created, response_type_normal, rs_optional), 3050 RSP_LINE("Update-existing", handle_update_existing, response_type_normal, 3051 rs_optional), 3052 RSP_LINE("Merged", handle_merged, response_type_normal, rs_essential), 3053 RSP_LINE("Patched", handle_patched, response_type_normal, rs_optional), 3054 RSP_LINE("Rcs-diff", handle_rcs_diff, response_type_normal, rs_optional), 3055 RSP_LINE("Mode", handle_mode, response_type_normal, rs_optional), 3056 RSP_LINE("Mod-time", handle_mod_time, response_type_normal, rs_optional), 3057 RSP_LINE("Removed", handle_removed, response_type_normal, rs_essential), 3058 RSP_LINE("Remove-entry", handle_remove_entry, response_type_normal, 3059 rs_optional), 3060 RSP_LINE("Set-static-directory", handle_set_static_directory, 3061 response_type_normal, 3062 rs_optional), 3063 RSP_LINE("Clear-static-directory", handle_clear_static_directory, 3064 response_type_normal, 3065 rs_optional), 3066 RSP_LINE("Set-sticky", handle_set_sticky, response_type_normal, 3067 rs_optional), 3068 RSP_LINE("Clear-sticky", handle_clear_sticky, response_type_normal, 3069 rs_optional), 3070 RSP_LINE("Edit-file", handle_edit_file, response_type_normal, 3071 rs_optional), 3072 RSP_LINE("Template", handle_template, response_type_normal, 3073 rs_optional), 3074 RSP_LINE("Clear-template", handle_clear_template, response_type_normal, 3075 rs_optional), 3076 RSP_LINE("Notified", handle_notified, response_type_normal, rs_optional), 3077 RSP_LINE("Module-expansion", handle_module_expansion, response_type_normal, 3078 rs_optional), 3079 RSP_LINE("Wrapper-rcsOption", handle_wrapper_rcs_option, 3080 response_type_normal, 3081 rs_optional), 3082 RSP_LINE("M", handle_m, response_type_normal, rs_essential), 3083 RSP_LINE("Mbinary", handle_mbinary, response_type_normal, rs_optional), 3084 RSP_LINE("E", handle_e, response_type_normal, rs_essential), 3085 RSP_LINE("F", handle_f, response_type_normal, rs_optional), 3086 RSP_LINE("MT", handle_mt, response_type_normal, rs_optional), 3087 /* Possibly should be response_type_error. */ 3088 RSP_LINE(NULL, NULL, response_type_normal, rs_essential) 3089 3090 #undef RSP_LINE 3091 }; 3092 3093 #endif /* CLIENT_SUPPORT or SERVER_SUPPORT */ 3094 #ifdef CLIENT_SUPPORT 3095 3096 3097 3098 /* 3099 * If LEN is 0, then send_to_server_via() computes string's length itself. 3100 * 3101 * Therefore, pass the real length when transmitting data that might 3102 * contain 0's. 3103 */ 3104 void 3105 send_to_server_via (struct buffer *via_buffer, const char *str, size_t len) 3106 { 3107 static int nbytes; 3108 3109 if (len == 0) 3110 len = strlen (str); 3111 3112 buf_output (via_buffer, str, len); 3113 3114 /* There is no reason not to send data to the server, so do it 3115 whenever we've accumulated enough information in the buffer to 3116 make it worth sending. */ 3117 nbytes += len; 3118 if (nbytes >= 2 * BUFFER_DATA_SIZE) 3119 { 3120 int status; 3121 3122 status = buf_send_output (via_buffer); 3123 if (status != 0) 3124 error (1, status, "error writing to server"); 3125 nbytes = 0; 3126 } 3127 } 3128 3129 3130 3131 void 3132 send_to_server (const char *str, size_t len) 3133 { 3134 send_to_server_via (global_to_server, str, len); 3135 } 3136 3137 3138 3139 /* Read up to LEN bytes from the server. Returns actual number of 3140 bytes read, which will always be at least one; blocks if there is 3141 no data available at all. Gives a fatal error on EOF or error. */ 3142 static size_t 3143 try_read_from_server( char *buf, size_t len ) 3144 { 3145 int status; 3146 size_t nread; 3147 char *data; 3148 3149 status = buf_read_data (global_from_server, len, &data, &nread); 3150 if (status != 0) 3151 { 3152 if (status == -1) 3153 error (1, 0, 3154 "end of file from server (consult above messages if any)"); 3155 else if (status == -2) 3156 error (1, 0, "out of memory"); 3157 else 3158 error (1, status, "reading from server"); 3159 } 3160 3161 memcpy (buf, data, nread); 3162 3163 return nread; 3164 } 3165 3166 3167 3168 /* 3169 * Read LEN bytes from the server or die trying. 3170 */ 3171 void 3172 read_from_server (char *buf, size_t len) 3173 { 3174 size_t red = 0; 3175 while (red < len) 3176 { 3177 red += try_read_from_server (buf + red, len - red); 3178 if (red == len) 3179 break; 3180 } 3181 } 3182 3183 3184 3185 /* Get some server responses and process them. 3186 * 3187 * RETURNS 3188 * 0 Success 3189 * 1 Error 3190 * 2 Redirect 3191 */ 3192 int 3193 get_server_responses (void) 3194 { 3195 struct response *rs; 3196 do 3197 { 3198 char *cmd; 3199 size_t len; 3200 3201 len = read_line (&cmd); 3202 for (rs = responses; rs->name; ++rs) 3203 if (!strncmp (cmd, rs->name, strlen (rs->name))) 3204 { 3205 size_t cmdlen = strlen (rs->name); 3206 if (cmd[cmdlen] == '\0') 3207 ; 3208 else if (cmd[cmdlen] == ' ') 3209 ++cmdlen; 3210 else 3211 /* 3212 * The first len characters match, but it's a different 3213 * response. e.g. the response is "oklahoma" but we 3214 * matched "ok". 3215 */ 3216 continue; 3217 (*rs->func) (cmd + cmdlen, len - cmdlen); 3218 break; 3219 } 3220 if (!rs->name) 3221 /* It's OK to print just to the first '\0'. */ 3222 /* We might want to handle control characters and the like 3223 in some other way other than just sending them to stdout. 3224 One common reason for this error is if people use :ext: 3225 with a version of rsh which is doing CRLF translation or 3226 something, and so the client gets "ok^M" instead of "ok". 3227 Right now that will tend to print part of this error 3228 message over the other part of it. It seems like we could 3229 do better (either in general, by quoting or omitting all 3230 control characters, and/or specifically, by detecting the CRLF 3231 case and printing a specific error message). */ 3232 error (0, 0, 3233 "warning: unrecognized response `%s' from cvs server", 3234 cmd); 3235 free (cmd); 3236 } while (rs->type == response_type_normal); 3237 3238 if (updated_fname) 3239 { 3240 /* Output the previous message now. This can happen 3241 if there was no Update-existing or other such 3242 response, due to the -n global option. */ 3243 cvs_output ("U ", 0); 3244 cvs_output (updated_fname, 0); 3245 cvs_output ("\n", 1); 3246 free (updated_fname); 3247 updated_fname = NULL; 3248 } 3249 3250 if (rs->type == response_type_redirect) return 2; 3251 if (rs->type == response_type_error) return 1; 3252 if (failure_exit) return 1; 3253 return 0; 3254 } 3255 3256 3257 3258 static inline void 3259 close_connection_to_server (struct buffer **to, struct buffer **from) 3260 { 3261 int status; 3262 3263 /* First we shut down GLOBAL_TO_SERVER. That tells the server that its 3264 * input is finished. It then shuts down the buffer it is sending to us, 3265 * at which point our shut down of GLOBAL_FROM_SERVER will complete. 3266 */ 3267 3268 TRACE (TRACE_FUNCTION, "close_connection_to_server ()"); 3269 3270 status = buf_shutdown (*to); 3271 if (status != 0) 3272 error (0, status, "shutting down buffer to server"); 3273 buf_free (*to); 3274 *to = NULL; 3275 3276 status = buf_shutdown (*from); 3277 if (status != 0) 3278 error (0, status, "shutting down buffer from server"); 3279 buf_free (*from); 3280 *from = NULL; 3281 } 3282 3283 3284 3285 /* Get the responses and then close the connection. */ 3286 3287 /* 3288 * Flag var; we'll set it in start_server() and not one of its 3289 * callees, such as start_rsh_server(). This means that there might 3290 * be a small window between the starting of the server and the 3291 * setting of this var, but all the code in that window shouldn't care 3292 * because it's busy checking return values to see if the server got 3293 * started successfully anyway. 3294 */ 3295 int server_started = 0; 3296 3297 int 3298 get_responses_and_close (void) 3299 { 3300 int errs = get_server_responses (); 3301 3302 /* The following is necessary when working with multiple cvsroots, at least 3303 * with commit. It used to be buried nicely in do_deferred_progs() before 3304 * that function was removed. I suspect it wouldn't be necessary if 3305 * call_in_directory() saved its working directory via save_cwd() before 3306 * changing its directory and restored the saved working directory via 3307 * restore_cwd() before exiting. Of course, calling CVS_CHDIR only once, 3308 * here, may be more efficient. 3309 */ 3310 if (toplevel_wd) 3311 { 3312 if (CVS_CHDIR (toplevel_wd) < 0) 3313 error (1, errno, "could not chdir to %s", toplevel_wd); 3314 } 3315 3316 if (client_prune_dirs) 3317 process_prune_candidates (); 3318 3319 close_connection_to_server (&global_to_server, &global_from_server); 3320 server_started = 0; 3321 3322 /* see if we need to sleep before returning to avoid time-stamp races */ 3323 if (last_register_time) 3324 sleep_past (last_register_time); 3325 3326 return errs; 3327 } 3328 3329 3330 3331 bool 3332 supported_request (const char *name) 3333 { 3334 struct request *rq; 3335 3336 for (rq = requests; rq->name; rq++) 3337 if (!strcmp (rq->name, name)) 3338 return (rq->flags & RQ_SUPPORTED) != 0; 3339 error (1, 0, "internal error: testing support for unknown request?"); 3340 /* NOTREACHED */ 3341 return 0; 3342 } 3343 3344 3345 3346 #if defined (AUTH_CLIENT_SUPPORT) || defined (SERVER_SUPPORT) || defined (HAVE_KERBEROS) || defined (HAVE_GSSAPI) 3347 3348 3349 /* Generic function to do port number lookup tasks. 3350 * 3351 * In order of precedence, will return: 3352 * getenv (envname), if defined 3353 * getservbyname (portname), if defined 3354 * defaultport 3355 */ 3356 static int 3357 get_port_number (const char *envname, const char *portname, int defaultport) 3358 { 3359 struct servent *s; 3360 char *port_s; 3361 3362 if (envname && (port_s = getenv (envname))) 3363 { 3364 int port = atoi (port_s); 3365 if (port <= 0) 3366 { 3367 error (0, 0, "%s must be a positive integer! If you", envname); 3368 error (0, 0, "are trying to force a connection via rsh, please"); 3369 error (0, 0, "put \":server:\" at the beginning of your CVSROOT"); 3370 error (1, 0, "variable."); 3371 } 3372 return port; 3373 } 3374 else if (portname && (s = getservbyname (portname, "tcp"))) 3375 return ntohs (s->s_port); 3376 else 3377 return defaultport; 3378 } 3379 3380 3381 3382 /* get the port number for a client to connect to based on the port 3383 * and method of a cvsroot_t. 3384 * 3385 * we do this here instead of in parse_cvsroot so that we can keep network 3386 * code confined to a localized area and also to delay the lookup until the 3387 * last possible moment so it remains possible to run cvs client commands that 3388 * skip opening connections to the server (i.e. skip network operations 3389 * entirely) 3390 * 3391 * and yes, I know none of the commands do that now, but here's to planning 3392 * for the future, eh? cheers. 3393 */ 3394 int 3395 get_cvs_port_number (const cvsroot_t *root) 3396 { 3397 3398 if (root->port) return root->port; 3399 3400 switch (root->method) 3401 { 3402 # ifdef HAVE_GSSAPI 3403 case gserver_method: 3404 # endif /* HAVE_GSSAPI */ 3405 # ifdef AUTH_CLIENT_SUPPORT 3406 case pserver_method: 3407 # endif /* AUTH_CLIENT_SUPPORT */ 3408 # if defined (AUTH_CLIENT_SUPPORT) || defined (HAVE_GSSAPI) 3409 return get_port_number ("CVS_CLIENT_PORT", "cvspserver", 3410 CVS_AUTH_PORT); 3411 # endif /* defined (AUTH_CLIENT_SUPPORT) || defined (HAVE_GSSAPI) */ 3412 # ifdef HAVE_KERBEROS 3413 case kserver_method: 3414 return get_port_number ("CVS_CLIENT_PORT", "cvs", CVS_PORT); 3415 # endif /* HAVE_KERBEROS */ 3416 default: 3417 error(1, EINVAL, 3418 "internal error: get_cvs_port_number called for invalid connection method (%s)", 3419 method_names[root->method]); 3420 break; 3421 } 3422 /* NOTREACHED */ 3423 return -1; 3424 } 3425 3426 3427 3428 /* get the port number for a client to connect to based on the proxy port 3429 * of a cvsroot_t. 3430 */ 3431 static int 3432 get_proxy_port_number (const cvsroot_t *root) 3433 { 3434 3435 if (root->proxy_port) return root->proxy_port; 3436 3437 return get_port_number ("CVS_PROXY_PORT", NULL, CVS_PROXY_PORT); 3438 } 3439 3440 3441 3442 void 3443 make_bufs_from_fds(int tofd, int fromfd, int child_pid, cvsroot_t *root, 3444 struct buffer **to_server_p, 3445 struct buffer **from_server_p, int is_sock) 3446 { 3447 # ifdef NO_SOCKET_TO_FD 3448 if (is_sock) 3449 { 3450 assert (tofd == fromfd); 3451 *to_server_p = socket_buffer_initialize (tofd, 0, NULL); 3452 *from_server_p = socket_buffer_initialize (tofd, 1, NULL); 3453 } 3454 else 3455 # endif /* NO_SOCKET_TO_FD */ 3456 { 3457 /* todo: some OS's don't need these calls... */ 3458 close_on_exec (tofd); 3459 close_on_exec (fromfd); 3460 3461 /* SCO 3 and AIX have a nasty bug in the I/O libraries which precludes 3462 fdopening the same file descriptor twice, so dup it if it is the 3463 same. */ 3464 if (tofd == fromfd) 3465 { 3466 fromfd = dup (tofd); 3467 if (fromfd < 0) 3468 error (1, errno, "cannot dup net connection"); 3469 } 3470 3471 /* These will use binary mode on systems which have it. */ 3472 /* 3473 * Also, we know that from_server is shut down second, so we pass 3474 * child_pid in there. In theory, it should be stored in both 3475 * buffers with a ref count... 3476 */ 3477 *to_server_p = fd_buffer_initialize (tofd, 0, root, false, NULL); 3478 *from_server_p = fd_buffer_initialize (fromfd, child_pid, root, 3479 true, NULL); 3480 } 3481 } 3482 #endif /* defined (AUTH_CLIENT_SUPPORT) || defined (SERVER_SUPPORT) || defined (HAVE_KERBEROS) || defined(HAVE_GSSAPI) */ 3483 3484 3485 3486 #if defined (AUTH_CLIENT_SUPPORT) || defined(HAVE_GSSAPI) 3487 /* Connect to the authenticating server. 3488 3489 If VERIFY_ONLY is non-zero, then just verify that the password is 3490 correct and then shutdown the connection. 3491 3492 If VERIFY_ONLY is 0, then really connect to the server. 3493 3494 If DO_GSSAPI is non-zero, then we use GSSAPI authentication rather 3495 than the pserver password authentication. 3496 3497 If we fail to connect or if access is denied, then die with fatal 3498 error. */ 3499 void 3500 connect_to_pserver (cvsroot_t *root, struct buffer **to_server_p, 3501 struct buffer **from_server_p, int verify_only, 3502 int do_gssapi) 3503 { 3504 int sock; 3505 int port_number, 3506 proxy_port_number = 0; /* Initialize to silence -Wall. Dumb. */ 3507 char no_passwd = 0; /* gets set if no password found */ 3508 struct buffer *to_server, *from_server; 3509 3510 port_number = get_cvs_port_number (root); 3511 3512 /* if we have a proxy connect to that instead */ 3513 if (root->proxy_hostname) 3514 { 3515 TRACE (TRACE_FUNCTION, "Connecting to %s:%d via proxy %s:%d.", 3516 root->hostname, port_number, root->proxy_hostname, 3517 proxy_port_number); 3518 proxy_port_number = get_proxy_port_number (root); 3519 sock = connect_to(root->proxy_hostname, proxy_port_number); 3520 } 3521 else 3522 { 3523 TRACE (TRACE_FUNCTION, "Connecting to %s:%d.", 3524 root->hostname, port_number); 3525 sock = connect_to(root->hostname, port_number); 3526 } 3527 3528 if (sock == -1) 3529 error (1, 0, "connect to %s:%d failed: %s", 3530 root->proxy_hostname ? root->proxy_hostname : root->hostname, 3531 root->proxy_hostname ? proxy_port_number : port_number, 3532 SOCK_STRERROR (SOCK_ERRNO)); 3533 3534 make_bufs_from_fds (sock, sock, 0, root, &to_server, &from_server, 1); 3535 3536 /* if we have proxy then connect to the proxy first */ 3537 if (root->proxy_hostname) 3538 { 3539 #define CONNECT_STRING "CONNECT %s:%d HTTP/1.0\r\n\r\n" 3540 /* Send a "CONNECT" command to proxy: */ 3541 char* read_buf; 3542 int codenum; 3543 size_t count; 3544 /* 4 characters for port covered by the length of %s & %d */ 3545 char* write_buf = Xasnprintf (NULL, &count, CONNECT_STRING, 3546 root->hostname, port_number); 3547 send_to_server_via (to_server, write_buf, count); 3548 3549 /* Wait for HTTP status code, bail out if you don't get back a 2xx 3550 * code. 3551 */ 3552 read_line_via (from_server, to_server, &read_buf); 3553 count = sscanf (read_buf, "%*s %d", &codenum); 3554 3555 if (count != 1 || (codenum / 100) != 2) 3556 error (1, 0, "proxy server %s:%d does not support http tunnelling", 3557 root->proxy_hostname, proxy_port_number); 3558 free (read_buf); 3559 free (write_buf); 3560 3561 /* Skip through remaining part of MIME header, recv_line 3562 consumes the trailing \n */ 3563 while (read_line_via (from_server, to_server, &read_buf) > 0) 3564 { 3565 if (read_buf[0] == '\r' || read_buf[0] == 0) 3566 { 3567 free (read_buf); 3568 break; 3569 } 3570 free (read_buf); 3571 } 3572 } 3573 3574 auth_server (root, to_server, from_server, verify_only, do_gssapi); 3575 3576 if (verify_only) 3577 { 3578 int status; 3579 3580 status = buf_shutdown (to_server); 3581 if (status != 0) 3582 error (0, status, "shutting down buffer to server"); 3583 buf_free (to_server); 3584 to_server = NULL; 3585 3586 status = buf_shutdown (from_server); 3587 if (status != 0) 3588 error (0, status, "shutting down buffer from server"); 3589 buf_free (from_server); 3590 from_server = NULL; 3591 3592 /* Don't need to set server_started = 0 since we don't set it to 1 3593 * until returning from this call. 3594 */ 3595 } 3596 else 3597 { 3598 *to_server_p = to_server; 3599 *from_server_p = from_server; 3600 } 3601 3602 return; 3603 } 3604 3605 3606 3607 static void 3608 auth_server (cvsroot_t *root, struct buffer *to_server, 3609 struct buffer *from_server, int verify_only, int do_gssapi) 3610 { 3611 char *username = NULL; /* the username we use to connect */ 3612 char no_passwd = 0; /* gets set if no password found */ 3613 3614 /* Run the authorization mini-protocol before anything else. */ 3615 if (do_gssapi) 3616 { 3617 # ifdef HAVE_GSSAPI 3618 int fd = buf_get_fd (to_server); 3619 struct stat s; 3620 3621 if ((fd < 0) || (fstat (fd, &s) < 0) || !S_ISSOCK(s.st_mode)) 3622 { 3623 error (1, 0, 3624 "gserver currently only enabled for socket connections"); 3625 } 3626 3627 if (! connect_to_gserver (root, fd, root->hostname)) 3628 { 3629 error (1, 0, 3630 "authorization failed: server %s rejected access to %s", 3631 root->hostname, root->directory); 3632 } 3633 # else /* ! HAVE_GSSAPI */ 3634 error (1, 0, 3635 "INTERNAL ERROR: This client does not support GSSAPI authentication"); 3636 # endif /* HAVE_GSSAPI */ 3637 } 3638 else /* ! do_gssapi */ 3639 { 3640 # ifdef AUTH_CLIENT_SUPPORT 3641 char *begin = NULL; 3642 char *password = NULL; 3643 char *end = NULL; 3644 3645 if (verify_only) 3646 { 3647 begin = "BEGIN VERIFICATION REQUEST"; 3648 end = "END VERIFICATION REQUEST"; 3649 } 3650 else 3651 { 3652 begin = "BEGIN AUTH REQUEST"; 3653 end = "END AUTH REQUEST"; 3654 } 3655 3656 /* Get the password, probably from ~/.cvspass. */ 3657 password = get_cvs_password (); 3658 username = root->username ? root->username : getcaller(); 3659 3660 /* Send the empty string by default. This is so anonymous CVS 3661 access doesn't require client to have done "cvs login". */ 3662 if (!password) 3663 { 3664 no_passwd = 1; 3665 password = scramble (""); 3666 } 3667 3668 /* Announce that we're starting the authorization protocol. */ 3669 send_to_server_via(to_server, begin, 0); 3670 send_to_server_via(to_server, "\012", 1); 3671 3672 /* Send the data the server needs. */ 3673 send_to_server_via(to_server, root->directory, 0); 3674 send_to_server_via(to_server, "\012", 1); 3675 send_to_server_via(to_server, username, 0); 3676 send_to_server_via(to_server, "\012", 1); 3677 send_to_server_via(to_server, password, 0); 3678 send_to_server_via(to_server, "\012", 1); 3679 3680 /* Announce that we're ending the authorization protocol. */ 3681 send_to_server_via(to_server, end, 0); 3682 send_to_server_via(to_server, "\012", 1); 3683 3684 /* Paranoia. */ 3685 free_cvs_password (password); 3686 password = NULL; 3687 # else /* ! AUTH_CLIENT_SUPPORT */ 3688 error (1, 0, "INTERNAL ERROR: This client does not support pserver authentication"); 3689 # endif /* AUTH_CLIENT_SUPPORT */ 3690 } /* if (do_gssapi) */ 3691 3692 { 3693 char *read_buf; 3694 3695 /* Loop, getting responses from the server. */ 3696 while (1) 3697 { 3698 read_line_via (from_server, to_server, &read_buf); 3699 3700 if (!strcmp (read_buf, "I HATE YOU")) 3701 { 3702 /* Authorization not granted. 3703 * 3704 * This is a little confusing since we can reach this while 3705 * loop in GSSAPI mode, but if GSSAPI authentication failed, 3706 * we already jumped to the rejected label (there is no case 3707 * where the connect_to_gserver function can return 1 and we 3708 * will not receive "I LOVE YOU" from the server, barring 3709 * broken connections and garbled messages, of course). The 3710 * GSSAPI case is also the case where username can be NULL 3711 * since username is initialized in the !gssapi section. 3712 * 3713 * i.e. This is a pserver specific error message and should be 3714 * since GSSAPI doesn't use username. 3715 */ 3716 error (0, 0, 3717 "authorization failed: server %s rejected access to %s for user %s", 3718 root->hostname, root->directory, 3719 username ? username : "(null)"); 3720 3721 /* Output a special error message if authentication was attempted 3722 with no password -- the user should be made aware that they may 3723 have missed a step. */ 3724 if (no_passwd) 3725 { 3726 error (0, 0, 3727 "used empty password; try \"cvs login\" with a real password"); 3728 } 3729 exit (EXIT_FAILURE); 3730 } 3731 else if (!strncmp (read_buf, "E ", 2)) 3732 { 3733 fprintf (stderr, "%s\n", read_buf + 2); 3734 3735 /* Continue with the authentication protocol. */ 3736 } 3737 else if (!strncmp (read_buf, "error ", 6)) 3738 { 3739 char *p; 3740 3741 /* First skip the code. */ 3742 p = read_buf + 6; 3743 while (*p != ' ' && *p != '\0') 3744 ++p; 3745 3746 /* Skip the space that follows the code. */ 3747 if (*p == ' ') 3748 ++p; 3749 3750 /* Now output the text. */ 3751 fprintf (stderr, "%s\n", p); 3752 exit (EXIT_FAILURE); 3753 } 3754 else if (!strcmp (read_buf, "I LOVE YOU")) 3755 { 3756 free (read_buf); 3757 break; 3758 } 3759 else 3760 { 3761 error (1, 0, 3762 "unrecognized auth response from %s: %s", 3763 root->hostname, read_buf); 3764 } 3765 free (read_buf); 3766 } 3767 } 3768 } 3769 #endif /* defined (AUTH_CLIENT_SUPPORT) || defined(HAVE_GSSAPI) */ 3770 3771 3772 3773 #if defined (CLIENT_SUPPORT) || defined (SERVER_SUPPORT) 3774 /* 3775 * Connect to a forked server process. 3776 */ 3777 static void 3778 connect_to_forked_server (cvsroot_t *root, struct buffer **to_server_p, 3779 struct buffer **from_server_p) 3780 { 3781 int tofd, fromfd; 3782 int child_pid; 3783 3784 /* This is pretty simple. All we need to do is choose the correct 3785 cvs binary and call piped_child. */ 3786 3787 char *command[3]; 3788 3789 command[0] = (root->cvs_server 3790 ? root->cvs_server : getenv ("CVS_SERVER")); 3791 if (!command[0]) 3792 # ifdef SERVER_SUPPORT 3793 /* FIXME: 3794 * I'm casting out the const below because I know that piped_child, the 3795 * only function we pass COMMAND to, accepts COMMAND as a 3796 * (char *const *) and won't alter it, and we don't alter it in this 3797 * function. This is yucky, there should be a way to declare COMMAND 3798 * such that this casting isn't needed, but I don't know how. If I 3799 * declare it as (const char *command[]), the compiler complains about 3800 * an incompatible arg 1 being passed to piped_child and if I declare 3801 * it as (char *const command[3]), then the compiler complains when I 3802 * assign values to command[i]. 3803 */ 3804 command[0] = (char *)program_path; 3805 # else /* SERVER_SUPPORT */ 3806 { 3807 error( 0, 0, "You must set the CVS_SERVER environment variable when" ); 3808 error( 0, 0, "using the :fork: access method." ); 3809 error( 1, 0, "This CVS was not compiled with server support." ); 3810 } 3811 # endif /* SERVER_SUPPORT */ 3812 3813 command[1] = "server"; 3814 command[2] = NULL; 3815 3816 TRACE (TRACE_FUNCTION, "Forking server: %s %s", 3817 command[0] ? command[0] : "(null)", command[1]); 3818 3819 child_pid = piped_child (command, &tofd, &fromfd, false); 3820 if (child_pid < 0) 3821 error (1, 0, "could not fork server process"); 3822 3823 make_bufs_from_fds (tofd, fromfd, child_pid, root, to_server_p, 3824 from_server_p, 0); 3825 } 3826 #endif /* CLIENT_SUPPORT || SERVER_SUPPORT */ 3827 3828 3829 3830 static int 3831 send_variable_proc (Node *node, void *closure) 3832 { 3833 send_to_server ("Set ", 0); 3834 send_to_server (node->key, 0); 3835 send_to_server ("=", 1); 3836 send_to_server (node->data, 0); 3837 send_to_server ("\012", 1); 3838 return 0; 3839 } 3840 3841 3842 3843 /* Open up the connection to the server and perform any necessary 3844 * authentication. 3845 */ 3846 void 3847 open_connection_to_server (cvsroot_t *root, struct buffer **to_server_p, 3848 struct buffer **from_server_p) 3849 { 3850 /* Note that generally speaking we do *not* fall back to a different 3851 way of connecting if the first one does not work. This is slow 3852 (*really* slow on a 14.4kbps link); the clean way to have a CVS 3853 which supports several ways of connecting is with access methods. */ 3854 3855 TRACE (TRACE_FUNCTION, "open_connection_to_server (%s)", root->original); 3856 3857 switch (root->method) 3858 { 3859 case pserver_method: 3860 #ifdef AUTH_CLIENT_SUPPORT 3861 /* Toss the return value. It will die with an error message if 3862 * anything goes wrong anyway. 3863 */ 3864 connect_to_pserver (root, to_server_p, from_server_p, 0, 0); 3865 #else /* AUTH_CLIENT_SUPPORT */ 3866 error (0, 0, "CVSROOT is set for a pserver access method but your"); 3867 error (1, 0, "CVS executable doesn't support it."); 3868 #endif /* AUTH_CLIENT_SUPPORT */ 3869 break; 3870 3871 case kserver_method: 3872 #if HAVE_KERBEROS 3873 start_kerberos4_server (root, to_server_p, 3874 from_server_p); 3875 #else /* !HAVE_KERBEROS */ 3876 error (0, 0, 3877 "CVSROOT is set for a kerberos access method but your"); 3878 error (1, 0, "CVS executable doesn't support it."); 3879 #endif /* HAVE_KERBEROS */ 3880 break; 3881 3882 case gserver_method: 3883 #ifdef HAVE_GSSAPI 3884 /* GSSAPI authentication is handled by the pserver. */ 3885 connect_to_pserver (root, to_server_p, from_server_p, 0, 1); 3886 #else /* !HAVE_GSSAPI */ 3887 error (0, 0, "CVSROOT is set for a GSSAPI access method but your"); 3888 error (1, 0, "CVS executable doesn't support it."); 3889 #endif /* HAVE_GSSAPI */ 3890 break; 3891 3892 case ext_method: 3893 #ifdef NO_EXT_METHOD 3894 error (0, 0, ":ext: method not supported by this port of CVS"); 3895 error (1, 0, "try :server: instead"); 3896 #else /* ! NO_EXT_METHOD */ 3897 start_rsh_server (root, to_server_p, 3898 from_server_p); 3899 #endif /* NO_EXT_METHOD */ 3900 break; 3901 3902 case server_method: 3903 #ifdef START_SERVER 3904 { 3905 int tofd, fromfd; 3906 START_SERVER (&tofd, &fromfd, getcaller (), 3907 root->username, 3908 root->hostname, 3909 root->directory); 3910 # ifdef START_SERVER_RETURNS_SOCKET 3911 make_bufs_from_fds (tofd, fromfd, 0, root, to_server_p, 3912 from_server_p, 1); 3913 # else /* ! START_SERVER_RETURNS_SOCKET */ 3914 make_bufs_from_fds (tofd, fromfd, 0, root, to_server_p, 3915 from_server_p, 0); 3916 # endif /* START_SERVER_RETURNS_SOCKET */ 3917 } 3918 #else /* ! START_SERVER */ 3919 /* FIXME: It should be possible to implement this portably, 3920 like pserver, which would get rid of the duplicated code 3921 in {vms,windows-NT,...}/startserver.c. */ 3922 error (1, 0, 3923 "the :server: access method is not supported by this port of CVS"); 3924 #endif /* START_SERVER */ 3925 break; 3926 3927 case fork_method: 3928 connect_to_forked_server (root, to_server_p, from_server_p); 3929 break; 3930 3931 default: 3932 error (1, 0, 3933 "(start_server internal error): unknown access method"); 3934 break; 3935 } 3936 3937 /* "Hi, I'm Darlene and I'll be your server tonight..." */ 3938 server_started = 1; 3939 } 3940 3941 3942 3943 /* Contact the server. */ 3944 void 3945 start_server (void) 3946 { 3947 bool rootless; 3948 int status; 3949 bool have_global; 3950 3951 do 3952 { 3953 /* Clear our static variables for this invocation. */ 3954 if (toplevel_repos) 3955 free (toplevel_repos); 3956 toplevel_repos = NULL; 3957 3958 open_connection_to_server (current_parsed_root, &global_to_server, 3959 &global_from_server); 3960 setup_logfiles ("CVS_CLIENT_LOG", &global_to_server, 3961 &global_from_server); 3962 3963 /* Clear static variables. */ 3964 if (toplevel_repos) 3965 { 3966 free (toplevel_repos); 3967 toplevel_repos = NULL; 3968 } 3969 if (last_repos) 3970 { 3971 free (last_repos); 3972 last_repos = NULL; 3973 } 3974 if (last_update_dir) 3975 { 3976 free (last_update_dir); 3977 last_update_dir = NULL; 3978 } 3979 stored_checksum_valid = 0; 3980 if (stored_mode) 3981 { 3982 free (stored_mode); 3983 stored_mode = NULL; 3984 } 3985 3986 rootless = !strcmp (cvs_cmd_name, "init"); 3987 if (!rootless) 3988 { 3989 send_to_server ("Root ", 0); 3990 send_to_server (current_parsed_root->directory, 0); 3991 send_to_server ("\012", 1); 3992 } 3993 3994 { 3995 struct response *rs; 3996 bool suppress_redirect = !current_parsed_root->redirect; 3997 3998 send_to_server ("Valid-responses", 0); 3999 4000 for (rs = responses; rs->name; ++rs) 4001 { 4002 if (suppress_redirect && !strcmp (rs->name, "Redirect")) 4003 continue; 4004 4005 send_to_server (" ", 0); 4006 send_to_server (rs->name, 0); 4007 } 4008 send_to_server ("\012", 1); 4009 } 4010 send_to_server ("valid-requests\012", 0); 4011 4012 if (get_server_responses ()) 4013 exit (EXIT_FAILURE); 4014 4015 have_global = supported_request ("Global_option"); 4016 4017 /* Encryption needs to come before compression. Good encryption can 4018 * render compression useless in the other direction. 4019 */ 4020 if (cvsencrypt && !rootless) 4021 { 4022 #ifdef ENCRYPTION 4023 /* Turn on encryption before turning on compression. We do 4024 * not want to try to compress the encrypted stream. Instead, 4025 * we want to encrypt the compressed stream. If we can't turn 4026 * on encryption, bomb out; don't let the user think the data 4027 * is being encrypted when it is not. 4028 */ 4029 # ifdef HAVE_KERBEROS 4030 if (current_parsed_root->method == kserver_method) 4031 { 4032 if (!supported_request ("Kerberos-encrypt")) 4033 error (1, 0, "This server does not support encryption"); 4034 send_to_server ("Kerberos-encrypt\012", 0); 4035 initialize_kerberos4_encryption_buffers (&global_to_server, 4036 &global_from_server); 4037 } 4038 else 4039 # endif /* HAVE_KERBEROS */ 4040 # ifdef HAVE_GSSAPI 4041 if (current_parsed_root->method == gserver_method) 4042 { 4043 if (!supported_request ("Gssapi-encrypt")) 4044 error (1, 0, "This server does not support encryption"); 4045 send_to_server ("Gssapi-encrypt\012", 0); 4046 initialize_gssapi_buffers (&global_to_server, 4047 &global_from_server); 4048 cvs_gssapi_encrypt = 1; 4049 } 4050 else 4051 # endif /* HAVE_GSSAPI */ 4052 error (1, 0, 4053 "Encryption is only supported when using GSSAPI or Kerberos"); 4054 #else /* ! ENCRYPTION */ 4055 error (1, 0, "This client does not support encryption"); 4056 #endif /* ! ENCRYPTION */ 4057 } 4058 4059 if (nolock && !noexec) 4060 { 4061 if (have_global) 4062 { 4063 send_to_server ("Global_option -u\012", 0); 4064 } 4065 else 4066 error (1, 0, 4067 "This server does not support the global -u option."); 4068 } 4069 /* Send this before compression to enable supression of the 4070 * "Forcing compression level Z" messages. 4071 */ 4072 if (quiet) 4073 { 4074 if (have_global) 4075 { 4076 send_to_server ("Global_option -q\012", 0); 4077 } 4078 else 4079 error (1, 0, 4080 "This server does not support the global -q option."); 4081 } 4082 if (really_quiet) 4083 { 4084 if (have_global) 4085 { 4086 send_to_server ("Global_option -Q\012", 0); 4087 } 4088 else 4089 error (1, 0, 4090 "This server does not support the global -Q option."); 4091 } 4092 4093 /* Compression needs to come before any of the rooted requests to 4094 * work with compression limits. 4095 */ 4096 if (!rootless && (gzip_level || force_gzip)) 4097 { 4098 if (supported_request ("Gzip-stream")) 4099 { 4100 char *gzip_level_buf = Xasprintf ("%d", gzip_level); 4101 send_to_server ("Gzip-stream ", 0); 4102 send_to_server (gzip_level_buf, 0); 4103 free (gzip_level_buf); 4104 send_to_server ("\012", 1); 4105 4106 /* All further communication with the server will be 4107 compressed. */ 4108 4109 global_to_server = 4110 compress_buffer_initialize (global_to_server, 0, 4111 gzip_level, NULL); 4112 global_from_server = 4113 compress_buffer_initialize (global_from_server, 1, 4114 gzip_level, NULL); 4115 } 4116 #ifndef NO_CLIENT_GZIP_PROCESS 4117 else if (supported_request ("gzip-file-contents")) 4118 { 4119 char *gzip_level_buf = Xasprintf ("%d", gzip_level); 4120 send_to_server ("gzip-file-contents ", 0); 4121 send_to_server (gzip_level_buf, 0); 4122 free (gzip_level_buf); 4123 send_to_server ("\012", 1); 4124 4125 file_gzip_level = gzip_level; 4126 } 4127 #endif 4128 else 4129 { 4130 fprintf (stderr, "server doesn't support gzip-file-contents\n"); 4131 /* Setting gzip_level to 0 prevents us from giving the 4132 error twice if update has to contact the server again 4133 to fetch unpatchable files. */ 4134 gzip_level = 0; 4135 } 4136 } 4137 4138 if (client_referrer && supported_request ("Referrer")) 4139 { 4140 send_to_server ("Referrer ", 0); 4141 send_to_server (client_referrer->original, 0); 4142 send_to_server ("\012", 0); 4143 } 4144 4145 /* FIXME: I think we should still be sending this for init. */ 4146 if (!rootless && supported_request ("Command-prep")) 4147 { 4148 send_to_server ("Command-prep ", 0); 4149 send_to_server (cvs_cmd_name, 0); 4150 send_to_server ("\012", 0); 4151 status = get_server_responses (); 4152 if (status == 1) exit (EXIT_FAILURE); 4153 if (status == 2) close_connection_to_server (&global_to_server, 4154 &global_from_server); 4155 } 4156 else status = 0; 4157 } while (status == 2); 4158 4159 4160 /* 4161 * Now handle global options. 4162 * 4163 * -H, -f, -d, -e should be handled OK locally. 4164 * 4165 * -b we ignore (treating it as a server installation issue). 4166 * FIXME: should be an error message. 4167 * 4168 * -v we print local version info; FIXME: Add a protocol request to get 4169 * the version from the server so we can print that too. 4170 * 4171 * -l -t -r -w -q -n and -Q need to go to the server. 4172 */ 4173 if (noexec) 4174 { 4175 if (have_global) 4176 { 4177 send_to_server ("Global_option -n\012", 0); 4178 } 4179 else 4180 error (1, 0, 4181 "This server does not support the global -n option."); 4182 } 4183 if (!cvswrite) 4184 { 4185 if (have_global) 4186 { 4187 send_to_server ("Global_option -r\012", 0); 4188 } 4189 else 4190 error (1, 0, 4191 "This server does not support the global -r option."); 4192 } 4193 if (trace) 4194 { 4195 if (have_global) 4196 { 4197 int count = trace; 4198 while (count--) send_to_server ("Global_option -t\012", 0); 4199 } 4200 else 4201 error (1, 0, 4202 "This server does not support the global -t option."); 4203 } 4204 4205 /* Find out about server-side cvswrappers. An extra network 4206 turnaround for cvs import seems to be unavoidable, unless we 4207 want to add some kind of client-side place to configure which 4208 filenames imply binary. For cvs add, we could avoid the 4209 problem by keeping a copy of the wrappers in CVSADM (the main 4210 reason to bother would be so we could make add work without 4211 contacting the server, I suspect). */ 4212 4213 if (!strcmp (cvs_cmd_name, "import") || !strcmp (cvs_cmd_name, "add")) 4214 { 4215 if (supported_request ("wrapper-sendme-rcsOptions")) 4216 { 4217 int err; 4218 send_to_server ("wrapper-sendme-rcsOptions\012", 0); 4219 err = get_server_responses (); 4220 if (err != 0) 4221 error (err, 0, "error reading from server"); 4222 } 4223 } 4224 4225 if (cvsauthenticate && ! cvsencrypt && !rootless) 4226 { 4227 /* Turn on authentication after turning on compression, so 4228 that we can compress the authentication information. We 4229 assume that encrypted data is always authenticated--the 4230 ability to decrypt the data stream is itself a form of 4231 authentication. */ 4232 #ifdef HAVE_GSSAPI 4233 if (current_parsed_root->method == gserver_method) 4234 { 4235 if (! supported_request ("Gssapi-authenticate")) 4236 error (1, 0, 4237 "This server does not support stream authentication"); 4238 send_to_server ("Gssapi-authenticate\012", 0); 4239 initialize_gssapi_buffers(&global_to_server, &global_from_server); 4240 4241 } 4242 else 4243 error (1, 0, "Stream authentication is only supported when using GSSAPI"); 4244 #else /* ! HAVE_GSSAPI */ 4245 error (1, 0, "This client does not support stream authentication"); 4246 #endif /* ! HAVE_GSSAPI */ 4247 } 4248 4249 /* If "Set" is not supported, just silently fail to send the variables. 4250 Users with an old server should get a useful error message when it 4251 fails to recognize the ${=foo} syntax. This way if someone uses 4252 several servers, some of which are new and some old, they can still 4253 set user variables in their .cvsrc without trouble. */ 4254 if (supported_request ("Set")) 4255 walklist (variable_list, send_variable_proc, NULL); 4256 } 4257 4258 4259 4260 /* Send an argument STRING. */ 4261 void 4262 send_arg (const char *string) 4263 { 4264 const char *p = string; 4265 4266 send_to_server ("Argument ", 0); 4267 4268 while (*p) 4269 { 4270 if (*p == '\n') 4271 send_to_server ("\012Argumentx ", 0); 4272 else 4273 send_to_server (p, 1); 4274 ++p; 4275 } 4276 send_to_server ("\012", 1); 4277 } 4278 4279 4280 4281 /* VERS->OPTIONS specifies whether the file is binary or not. NOTE: BEFORE 4282 using any other fields of the struct vers, we would need to fix 4283 client_process_import_file to set them up. */ 4284 static void 4285 send_modified (const char *file, const char *short_pathname, Vers_TS *vers) 4286 { 4287 /* File was modified, send it. */ 4288 struct stat sb; 4289 int fd; 4290 unsigned char *buf; 4291 char *mode_string; 4292 size_t bufsize; 4293 int bin; 4294 4295 TRACE (TRACE_FUNCTION, "Sending file `%s' to server", file); 4296 4297 /* Don't think we can assume fstat exists. */ 4298 if (stat (file, &sb) < 0) 4299 error (1, errno, "reading %s", short_pathname); 4300 4301 mode_string = mode_to_string (sb.st_mode); 4302 4303 /* Beware: on systems using CRLF line termination conventions, 4304 the read and write functions will convert CRLF to LF, so the 4305 number of characters read is not the same as sb.st_size. Text 4306 files should always be transmitted using the LF convention, so 4307 we don't want to disable this conversion. */ 4308 bufsize = sb.st_size; 4309 buf = xmalloc (bufsize); 4310 4311 /* Is the file marked as containing binary data by the "-kb" flag? 4312 If so, make sure to open it in binary mode: */ 4313 4314 if (vers && vers->options) 4315 bin = !strcmp (vers->options, "-kb"); 4316 else 4317 bin = 0; 4318 4319 #ifdef BROKEN_READWRITE_CONVERSION 4320 if (!bin) 4321 { 4322 /* If only stdio, not open/write/etc., do text/binary 4323 conversion, use convert_file which can compensate 4324 (FIXME: we could just use stdio instead which would 4325 avoid the whole problem). */ 4326 char *tfile = Xasprintf ("%s.CVSBFCTMP", file); 4327 convert_file (file, O_RDONLY, 4328 tfile, O_WRONLY | O_CREAT | O_TRUNC | OPEN_BINARY); 4329 fd = CVS_OPEN (tfile, O_RDONLY | OPEN_BINARY); 4330 if (fd < 0) 4331 error (1, errno, "reading %s", short_pathname); 4332 free (tfile); 4333 } 4334 else 4335 fd = CVS_OPEN (file, O_RDONLY | OPEN_BINARY); 4336 #else 4337 fd = CVS_OPEN (file, O_RDONLY | (bin ? OPEN_BINARY : 0)); 4338 #endif 4339 4340 if (fd < 0) 4341 error (1, errno, "reading %s", short_pathname); 4342 4343 if (file_gzip_level && sb.st_size > 100) 4344 { 4345 size_t newsize = 0; 4346 4347 if (read_and_gzip (fd, short_pathname, &buf, 4348 &bufsize, &newsize, 4349 file_gzip_level)) 4350 error (1, 0, "aborting due to compression error"); 4351 4352 if (close (fd) < 0) 4353 error (0, errno, "warning: can't close %s", short_pathname); 4354 4355 { 4356 char tmp[80]; 4357 4358 send_to_server ("Modified ", 0); 4359 send_to_server (file, 0); 4360 send_to_server ("\012", 1); 4361 send_to_server (mode_string, 0); 4362 send_to_server ("\012z", 2); 4363 sprintf (tmp, "%lu\n", (unsigned long) newsize); 4364 send_to_server (tmp, 0); 4365 4366 send_to_server (buf, newsize); 4367 } 4368 } 4369 else 4370 { 4371 int newsize; 4372 4373 { 4374 unsigned char *bufp = buf; 4375 int len; 4376 4377 /* FIXME: This is gross. It assumes that we might read 4378 less than st_size bytes (true on NT), but not more. 4379 Instead of this we should just be reading a block of 4380 data (e.g. 8192 bytes), writing it to the network, and 4381 so on until EOF. */ 4382 while ((len = read (fd, bufp, (buf + sb.st_size) - bufp)) > 0) 4383 bufp += len; 4384 4385 if (len < 0) 4386 error (1, errno, "reading %s", short_pathname); 4387 4388 newsize = bufp - buf; 4389 } 4390 if (close (fd) < 0) 4391 error (0, errno, "warning: can't close %s", short_pathname); 4392 4393 { 4394 char tmp[80]; 4395 4396 send_to_server ("Modified ", 0); 4397 send_to_server (file, 0); 4398 send_to_server ("\012", 1); 4399 send_to_server (mode_string, 0); 4400 send_to_server ("\012", 1); 4401 sprintf (tmp, "%lu\012", (unsigned long) newsize); 4402 send_to_server (tmp, 0); 4403 } 4404 #ifdef BROKEN_READWRITE_CONVERSION 4405 if (!bin) 4406 { 4407 char *tfile = Xasprintf ("%s.CVSBFCTMP", file); 4408 if (CVS_UNLINK (tfile) < 0) 4409 error (0, errno, "warning: can't remove temp file %s", tfile); 4410 free (tfile); 4411 } 4412 #endif 4413 4414 /* 4415 * Note that this only ends with a newline if the file ended with 4416 * one. 4417 */ 4418 if (newsize > 0) 4419 send_to_server (buf, newsize); 4420 } 4421 free (buf); 4422 free (mode_string); 4423 } 4424 4425 4426 4427 /* The address of an instance of this structure is passed to 4428 send_fileproc, send_filesdoneproc, and send_direntproc, as the 4429 callerdat parameter. */ 4430 struct send_data 4431 { 4432 /* Each of the following flags are zero for clear or nonzero for set. */ 4433 int build_dirs; 4434 int force; 4435 int no_contents; 4436 int backup_modified; 4437 }; 4438 4439 /* Deal with one file. */ 4440 static int 4441 send_fileproc (void *callerdat, struct file_info *finfo) 4442 { 4443 struct send_data *args = callerdat; 4444 Vers_TS *vers; 4445 struct file_info xfinfo; 4446 /* File name to actually use. Might differ in case from 4447 finfo->file. */ 4448 const char *filename; 4449 4450 send_a_repository ("", finfo->repository, finfo->update_dir); 4451 4452 xfinfo = *finfo; 4453 xfinfo.repository = NULL; 4454 xfinfo.rcs = NULL; 4455 vers = Version_TS (&xfinfo, NULL, NULL, NULL, 0, 0); 4456 4457 if (vers->entdata) 4458 filename = vers->entdata->user; 4459 else 4460 filename = finfo->file; 4461 4462 if (vers->vn_user) 4463 { 4464 /* The Entries request. */ 4465 send_to_server ("Entry /", 0); 4466 send_to_server (filename, 0); 4467 send_to_server ("/", 0); 4468 send_to_server (vers->vn_user, 0); 4469 send_to_server ("/", 0); 4470 if (vers->ts_conflict) 4471 { 4472 if (vers->ts_user && !strcmp (vers->ts_conflict, vers->ts_user)) 4473 send_to_server ("+=", 0); 4474 else 4475 send_to_server ("+modified", 0); 4476 } 4477 send_to_server ("/", 0); 4478 send_to_server (vers->entdata ? vers->entdata->options : vers->options, 4479 0); 4480 send_to_server ("/", 0); 4481 if (vers->entdata && vers->entdata->tag) 4482 { 4483 send_to_server ("T", 0); 4484 send_to_server (vers->entdata->tag, 0); 4485 } 4486 else if (vers->entdata && vers->entdata->date) 4487 { 4488 send_to_server ("D", 0); 4489 send_to_server (vers->entdata->date, 0); 4490 } 4491 send_to_server ("\012", 1); 4492 } 4493 else 4494 { 4495 /* It seems a little silly to re-read this on each file, but 4496 send_dirent_proc doesn't get called if filenames are specified 4497 explicitly on the command line. */ 4498 wrap_add_file (CVSDOTWRAPPER, 1); 4499 4500 if (wrap_name_has (filename, WRAP_RCSOPTION)) 4501 { 4502 /* No "Entry", but the wrappers did give us a kopt so we better 4503 send it with "Kopt". As far as I know this only happens 4504 for "cvs add". Question: is there any reason why checking 4505 for options from wrappers isn't done in Version_TS? 4506 4507 Note: it might have been better to just remember all the 4508 kopts on the client side, rather than send them to the server, 4509 and have it send us back the same kopts. But that seemed like 4510 a bigger change than I had in mind making now. */ 4511 4512 if (supported_request ("Kopt")) 4513 { 4514 char *opt; 4515 4516 send_to_server ("Kopt ", 0); 4517 opt = wrap_rcsoption (filename, 1); 4518 send_to_server (opt, 0); 4519 send_to_server ("\012", 1); 4520 free (opt); 4521 } 4522 else 4523 error (0, 0, "\ 4524 warning: ignoring -k options due to server limitations"); 4525 } 4526 } 4527 4528 if (!vers->ts_user) 4529 { 4530 /* 4531 * Do we want to print "file was lost" like normal CVS? 4532 * Would it always be appropriate? 4533 */ 4534 /* File no longer exists. Don't do anything, missing files 4535 just happen. */ 4536 } 4537 else if (!vers->ts_rcs || args->force 4538 || strcmp (vers->ts_conflict 4539 ? vers->ts_conflict : vers->ts_rcs, vers->ts_user) 4540 || (vers->ts_conflict && !strcmp (cvs_cmd_name, "diff"))) 4541 { 4542 if (args->no_contents 4543 && supported_request ("Is-modified")) 4544 { 4545 send_to_server ("Is-modified ", 0); 4546 send_to_server (filename, 0); 4547 send_to_server ("\012", 1); 4548 } 4549 else 4550 send_modified (filename, finfo->fullname, vers); 4551 4552 if (args->backup_modified) 4553 { 4554 char *bakname; 4555 bakname = backup_file (filename, vers->vn_user); 4556 /* This behavior is sufficiently unexpected to 4557 justify overinformativeness, I think. */ 4558 if (! really_quiet) 4559 printf ("(Locally modified %s moved to %s)\n", 4560 filename, bakname); 4561 free (bakname); 4562 } 4563 } 4564 else 4565 { 4566 send_to_server ("Unchanged ", 0); 4567 send_to_server (filename, 0); 4568 send_to_server ("\012", 1); 4569 } 4570 4571 /* if this directory has an ignore list, add this file to it */ 4572 if (ignlist) 4573 { 4574 Node *p; 4575 4576 p = getnode (); 4577 p->type = FILES; 4578 p->key = xstrdup (finfo->file); 4579 (void) addnode (ignlist, p); 4580 } 4581 4582 freevers_ts (&vers); 4583 return 0; 4584 } 4585 4586 4587 4588 static void 4589 send_ignproc (const char *file, const char *dir) 4590 { 4591 if (ign_inhibit_server || !supported_request ("Questionable")) 4592 { 4593 if (dir[0] != '\0') 4594 (void) printf ("? %s/%s\n", dir, file); 4595 else 4596 (void) printf ("? %s\n", file); 4597 } 4598 else 4599 { 4600 send_to_server ("Questionable ", 0); 4601 send_to_server (file, 0); 4602 send_to_server ("\012", 1); 4603 } 4604 } 4605 4606 4607 4608 static int 4609 send_filesdoneproc (void *callerdat, int err, const char *repository, 4610 const char *update_dir, List *entries) 4611 { 4612 /* if this directory has an ignore list, process it then free it */ 4613 if (ignlist) 4614 { 4615 ignore_files (ignlist, entries, update_dir, send_ignproc); 4616 dellist (&ignlist); 4617 } 4618 4619 return err; 4620 } 4621 4622 4623 4624 /* 4625 * send_dirent_proc () is called back by the recursion processor before a 4626 * sub-directory is processed for update. 4627 * A return code of 0 indicates the directory should be 4628 * processed by the recursion code. A return of non-zero indicates the 4629 * recursion code should skip this directory. 4630 * 4631 */ 4632 static Dtype 4633 send_dirent_proc (void *callerdat, const char *dir, const char *repository, 4634 const char *update_dir, List *entries) 4635 { 4636 struct send_data *args = callerdat; 4637 int dir_exists; 4638 char *cvsadm_name; 4639 4640 if (ignore_directory (update_dir)) 4641 { 4642 /* print the warm fuzzy message */ 4643 if (!quiet) 4644 error (0, 0, "Ignoring %s", update_dir); 4645 return R_SKIP_ALL; 4646 } 4647 4648 /* 4649 * If the directory does not exist yet (e.g. "cvs update -d foo"), 4650 * no need to send any files from it. If the directory does not 4651 * have a CVS directory, then we pretend that it does not exist. 4652 * Otherwise, we will fail when trying to open the Entries file. 4653 * This case will happen when checking out a module defined as 4654 * ``-a .''. 4655 */ 4656 cvsadm_name = Xasprintf ("%s/%s", dir, CVSADM); 4657 dir_exists = isdir (cvsadm_name); 4658 free (cvsadm_name); 4659 4660 /* 4661 * If there is an empty directory (e.g. we are doing `cvs add' on a 4662 * newly-created directory), the server still needs to know about it. 4663 */ 4664 4665 if (dir_exists) 4666 { 4667 /* 4668 * Get the repository from a CVS/Repository file whenever possible. 4669 * The repository variable is wrong if the names in the local 4670 * directory don't match the names in the repository. 4671 */ 4672 char *repos = Name_Repository (dir, update_dir); 4673 send_a_repository (dir, repos, update_dir); 4674 free (repos); 4675 4676 /* initialize the ignore list for this directory */ 4677 ignlist = getlist (); 4678 } 4679 else 4680 { 4681 /* It doesn't make sense to send a non-existent directory, 4682 because there is no way to get the correct value for 4683 the repository (I suppose maybe via the expand-modules 4684 request). In the case where the "obvious" choice for 4685 repository is correct, the server can figure out whether 4686 to recreate the directory; in the case where it is wrong 4687 (that is, does not match what modules give us), we might as 4688 well just fail to recreate it. 4689 4690 Checking for noexec is a kludge for "cvs -n add dir". */ 4691 /* Don't send a non-existent directory unless we are building 4692 new directories (build_dirs is true). Otherwise, CVS may 4693 see a D line in an Entries file, and recreate a directory 4694 which the user removed by hand. */ 4695 if (args->build_dirs && noexec) 4696 send_a_repository (dir, repository, update_dir); 4697 } 4698 4699 return dir_exists ? R_PROCESS : R_SKIP_ALL; 4700 } 4701 4702 4703 4704 /* 4705 * send_dirleave_proc () is called back by the recursion code upon leaving 4706 * a directory. All it does is delete the ignore list if it hasn't already 4707 * been done (by send_filesdone_proc). 4708 */ 4709 /* ARGSUSED */ 4710 static int 4711 send_dirleave_proc (void *callerdat, const char *dir, int err, 4712 const char *update_dir, List *entries ) 4713 { 4714 4715 /* Delete the ignore list if it hasn't already been done. */ 4716 if (ignlist) 4717 dellist (&ignlist); 4718 return err; 4719 } 4720 4721 4722 4723 /* 4724 * Send each option in an array to the server, one by one. 4725 * argv might be "--foo=bar", "-C", "5", "-y". 4726 */ 4727 4728 void 4729 send_options (int argc, char * const *argv) 4730 { 4731 int i; 4732 for (i = 0; i < argc; i++) 4733 send_arg (argv[i]); 4734 } 4735 4736 4737 4738 /* Send the names of all the argument files to the server. */ 4739 void 4740 send_file_names (int argc, char **argv, unsigned int flags) 4741 { 4742 int i; 4743 4744 /* The fact that we do this here as well as start_recursion is a bit 4745 of a performance hit. Perhaps worth cleaning up someday. */ 4746 if (flags & SEND_EXPAND_WILD) 4747 expand_wild (argc, argv, &argc, &argv); 4748 4749 for (i = 0; i < argc; ++i) 4750 { 4751 char buf[1]; 4752 char *p; 4753 #ifdef FILENAMES_CASE_INSENSITIVE 4754 char *line = NULL; 4755 #endif /* FILENAMES_CASE_INSENSITIVE */ 4756 4757 if (arg_should_not_be_sent_to_server (argv[i])) 4758 continue; 4759 4760 #ifdef FILENAMES_CASE_INSENSITIVE 4761 /* We want to send the path as it appears in the 4762 CVS/Entries files. We put this inside an ifdef 4763 to avoid doing all these system calls in 4764 cases where fncmp is just strcmp anyway. */ 4765 /* The isdir (CVSADM) check could more gracefully be replaced 4766 with a way of having Entries_Open report back the 4767 error to us and letting us ignore existence_error. 4768 Or some such. */ 4769 { 4770 List *stack; 4771 size_t line_len = 0; 4772 char *q, *r; 4773 struct saved_cwd sdir; 4774 4775 /* Split the argument onto the stack. */ 4776 stack = getlist(); 4777 r = xstrdup (argv[i]); 4778 /* It's okay to discard the const from the last_component return 4779 * below since we know we passed in an arg that was not const. 4780 */ 4781 while ((q = (char *)last_component (r)) != r) 4782 { 4783 push (stack, xstrdup (q)); 4784 *--q = '\0'; 4785 } 4786 push (stack, r); 4787 4788 /* Normalize the path into outstr. */ 4789 save_cwd (&sdir); 4790 while (q = pop (stack)) 4791 { 4792 Node *node = NULL; 4793 if (isdir (CVSADM)) 4794 { 4795 List *entries; 4796 4797 /* Note that if we are adding a directory, 4798 the following will read the entry 4799 that we just wrote there, that is, we 4800 will get the case specified on the 4801 command line, not the case of the 4802 directory in the filesystem. This 4803 is correct behavior. */ 4804 entries = Entries_Open (0, NULL); 4805 node = findnode_fn (entries, q); 4806 if (node) 4807 { 4808 /* Add the slash unless this is our first element. */ 4809 if (line_len) 4810 xrealloc_and_strcat (&line, &line_len, "/"); 4811 xrealloc_and_strcat (&line, &line_len, node->key); 4812 delnode (node); 4813 } 4814 Entries_Close (entries); 4815 } 4816 4817 /* If node is still NULL then we either didn't find CVSADM or 4818 * we didn't find an entry there. 4819 */ 4820 if (!node) 4821 { 4822 /* Add the slash unless this is our first element. */ 4823 if (line_len) 4824 xrealloc_and_strcat (&line, &line_len, "/"); 4825 xrealloc_and_strcat (&line, &line_len, q); 4826 break; 4827 } 4828 4829 /* And descend the tree. */ 4830 if (isdir (q)) 4831 CVS_CHDIR (q); 4832 free (q); 4833 } 4834 restore_cwd (&sdir); 4835 free_cwd (&sdir); 4836 4837 /* Now put everything we didn't find entries for back on. */ 4838 while (q = pop (stack)) 4839 { 4840 if (line_len) 4841 xrealloc_and_strcat (&line, &line_len, "/"); 4842 xrealloc_and_strcat (&line, &line_len, q); 4843 free (q); 4844 } 4845 4846 p = line; 4847 4848 dellist (&stack); 4849 } 4850 #else /* !FILENAMES_CASE_INSENSITIVE */ 4851 p = argv[i]; 4852 #endif /* FILENAMES_CASE_INSENSITIVE */ 4853 4854 send_to_server ("Argument ", 0); 4855 4856 while (*p) 4857 { 4858 if (*p == '\n') 4859 { 4860 send_to_server ("\012Argumentx ", 0); 4861 } 4862 else if (ISSLASH (*p)) 4863 { 4864 buf[0] = '/'; 4865 send_to_server (buf, 1); 4866 } 4867 else 4868 { 4869 buf[0] = *p; 4870 send_to_server (buf, 1); 4871 } 4872 ++p; 4873 } 4874 send_to_server ("\012", 1); 4875 #ifdef FILENAMES_CASE_INSENSITIVE 4876 free (line); 4877 #endif /* FILENAMES_CASE_INSENSITIVE */ 4878 } 4879 4880 if (flags & SEND_EXPAND_WILD) 4881 { 4882 int i; 4883 for (i = 0; i < argc; ++i) 4884 free (argv[i]); 4885 free (argv); 4886 } 4887 } 4888 4889 4890 4891 /* Calculate and send max-dotdot to the server */ 4892 static void 4893 send_max_dotdot (argc, argv) 4894 int argc; 4895 char **argv; 4896 { 4897 int i; 4898 int level = 0; 4899 int max_level = 0; 4900 4901 /* Send Max-dotdot if needed. */ 4902 for (i = 0; i < argc; ++i) 4903 { 4904 level = pathname_levels (argv[i]); 4905 if (level > 0) 4906 { 4907 if (!uppaths) uppaths = getlist(); 4908 push_string (uppaths, xstrdup (argv[i])); 4909 } 4910 if (level > max_level) 4911 max_level = level; 4912 } 4913 4914 if (max_level > 0) 4915 { 4916 if (supported_request ("Max-dotdot")) 4917 { 4918 char buf[10]; 4919 sprintf (buf, "%d", max_level); 4920 4921 send_to_server ("Max-dotdot ", 0); 4922 send_to_server (buf, 0); 4923 send_to_server ("\012", 1); 4924 } 4925 else 4926 { 4927 error (1, 0, 4928 "backreference in path (`..') not supported by old (pre-Max-dotdot) servers"); 4929 } 4930 } 4931 } 4932 4933 4934 4935 /* Send Repository, Modified and Entry. argc and argv contain only 4936 the files to operate on (or empty for everything), not options. 4937 local is nonzero if we should not recurse (-l option). flags & 4938 SEND_BUILD_DIRS is nonzero if nonexistent directories should be 4939 sent. flags & SEND_FORCE is nonzero if we should send unmodified 4940 files to the server as though they were modified. flags & 4941 SEND_NO_CONTENTS means that this command only needs to know 4942 _whether_ a file is modified, not the contents. Also sends Argument 4943 lines for argc and argv, so should be called after options are sent. */ 4944 void 4945 send_files (int argc, char **argv, int local, int aflag, unsigned int flags) 4946 { 4947 struct send_data args; 4948 int err; 4949 4950 send_max_dotdot (argc, argv); 4951 4952 /* 4953 * aflag controls whether the tag/date is copied into the vers_ts. 4954 * But we don't actually use it, so I don't think it matters what we pass 4955 * for aflag here. 4956 */ 4957 args.build_dirs = flags & SEND_BUILD_DIRS; 4958 args.force = flags & SEND_FORCE; 4959 args.no_contents = flags & SEND_NO_CONTENTS; 4960 args.backup_modified = flags & BACKUP_MODIFIED_FILES; 4961 err = start_recursion 4962 (send_fileproc, send_filesdoneproc, send_dirent_proc, 4963 send_dirleave_proc, &args, argc, argv, local, W_LOCAL, aflag, 4964 CVS_LOCK_NONE, NULL, 0, NULL); 4965 if (err) 4966 exit (EXIT_FAILURE); 4967 if (!toplevel_repos) 4968 /* 4969 * This happens if we are not processing any files, 4970 * or for checkouts in directories without any existing stuff 4971 * checked out. The following assignment is correct for the 4972 * latter case; I don't think toplevel_repos matters for the 4973 * former. 4974 */ 4975 toplevel_repos = xstrdup (current_parsed_root->directory); 4976 send_repository ("", toplevel_repos, "."); 4977 } 4978 4979 4980 4981 void 4982 client_import_setup (char *repository) 4983 { 4984 if (!toplevel_repos) /* should always be true */ 4985 send_a_repository ("", repository, ""); 4986 } 4987 4988 4989 4990 /* 4991 * Process the argument import file. 4992 */ 4993 int 4994 client_process_import_file (char *message, char *vfile, char *vtag, int targc, 4995 char *targv[], char *repository, 4996 int all_files_binary, 4997 int modtime /* Nonzero for "import -d". */ ) 4998 { 4999 char *update_dir; 5000 char *fullname; 5001 Vers_TS vers; 5002 5003 assert (toplevel_repos); 5004 5005 if (strncmp (repository, toplevel_repos, strlen (toplevel_repos))) 5006 error (1, 0, 5007 "internal error: pathname `%s' doesn't specify file in `%s'", 5008 repository, toplevel_repos); 5009 5010 if (!strcmp (repository, toplevel_repos)) 5011 { 5012 update_dir = ""; 5013 fullname = xstrdup (vfile); 5014 } 5015 else 5016 { 5017 update_dir = repository + strlen (toplevel_repos) + 1; 5018 5019 fullname = Xasprintf ("%s/%s", update_dir, vfile); 5020 } 5021 5022 send_a_repository ("", repository, update_dir); 5023 if (all_files_binary) 5024 vers.options = xstrdup ("-kb"); 5025 else 5026 vers.options = wrap_rcsoption (vfile, 1); 5027 5028 if (vers.options) 5029 { 5030 if (supported_request ("Kopt")) 5031 { 5032 send_to_server ("Kopt ", 0); 5033 send_to_server (vers.options, 0); 5034 send_to_server ("\012", 1); 5035 } 5036 else 5037 error (0, 0, 5038 "warning: ignoring -k options due to server limitations"); 5039 } 5040 if (modtime) 5041 { 5042 if (supported_request ("Checkin-time")) 5043 { 5044 struct stat sb; 5045 char *rcsdate; 5046 char netdate[MAXDATELEN]; 5047 5048 if (stat (vfile, &sb) < 0) 5049 error (1, errno, "cannot stat %s", fullname); 5050 rcsdate = date_from_time_t (sb.st_mtime); 5051 date_to_internet (netdate, rcsdate); 5052 free (rcsdate); 5053 5054 send_to_server ("Checkin-time ", 0); 5055 send_to_server (netdate, 0); 5056 send_to_server ("\012", 1); 5057 } 5058 else 5059 error (0, 0, 5060 "warning: ignoring -d option due to server limitations"); 5061 } 5062 send_modified (vfile, fullname, &vers); 5063 if (vers.options) 5064 free (vers.options); 5065 free (fullname); 5066 return 0; 5067 } 5068 5069 5070 5071 void 5072 client_import_done (void) 5073 { 5074 if (!toplevel_repos) 5075 /* 5076 * This happens if we are not processing any files, 5077 * or for checkouts in directories without any existing stuff 5078 * checked out. The following assignment is correct for the 5079 * latter case; I don't think toplevel_repos matters for the 5080 * former. 5081 */ 5082 /* FIXME: "can't happen" now that we call client_import_setup 5083 at the beginning. */ 5084 toplevel_repos = xstrdup (current_parsed_root->directory); 5085 send_repository ("", toplevel_repos, "."); 5086 } 5087 5088 5089 5090 void 5091 client_notify (const char *repository, const char *update_dir, 5092 const char *filename, int notif_type, const char *val) 5093 { 5094 char buf[2]; 5095 5096 send_a_repository ("", repository, update_dir); 5097 send_to_server ("Notify ", 0); 5098 send_to_server (filename, 0); 5099 send_to_server ("\012", 1); 5100 buf[0] = notif_type; 5101 buf[1] = '\0'; 5102 send_to_server (buf, 1); 5103 send_to_server ("\t", 1); 5104 send_to_server (val, 0); 5105 } 5106 5107 5108 5109 /* 5110 * Send an option with an argument, dealing correctly with newlines in 5111 * the argument. If ARG is NULL, forget the whole thing. 5112 */ 5113 void 5114 option_with_arg (const char *option, const char *arg) 5115 { 5116 if (!arg) 5117 return; 5118 5119 send_to_server ("Argument ", 0); 5120 send_to_server (option, 0); 5121 send_to_server ("\012", 1); 5122 5123 send_arg (arg); 5124 } 5125 5126 5127 5128 /* Send a date to the server. The input DATE is in RCS format. 5129 The time will be GMT. 5130 5131 We then convert that to the format required in the protocol 5132 (including the "-D" option) and send it. According to 5133 cvsclient.texi, RFC 822/1123 format is preferred. */ 5134 void 5135 client_senddate (const char *date) 5136 { 5137 char buf[MAXDATELEN]; 5138 5139 date_to_internet (buf, date); 5140 option_with_arg ("-D", buf); 5141 } 5142 5143 5144 5145 void 5146 send_init_command (void) 5147 { 5148 /* This is here because we need the current_parsed_root->directory variable. */ 5149 send_to_server ("init ", 0); 5150 send_to_server (current_parsed_root->directory, 0); 5151 send_to_server ("\012", 0); 5152 } 5153 5154 5155 5156 #if defined AUTH_CLIENT_SUPPORT || defined HAVE_KERBEROS || defined HAVE_GSSAPI 5157 5158 static int 5159 connect_to(char *hostname, unsigned int port) 5160 { 5161 struct addrinfo hints, *res, *res0 = NULL; 5162 char pbuf[10]; 5163 int e, sock; 5164 5165 memset(&hints, 0, sizeof(hints)); 5166 hints.ai_family = PF_UNSPEC; 5167 hints.ai_socktype = SOCK_STREAM; 5168 hints.ai_flags = AI_CANONNAME; 5169 5170 snprintf(pbuf, sizeof(pbuf), "%d", port); 5171 e = getaddrinfo(hostname, pbuf, &hints, &res0); 5172 if (e) 5173 { 5174 error (1, 0, "%s", gai_strerror(e)); 5175 } 5176 sock = -1; 5177 for (res = res0; res; res = res->ai_next) { 5178 sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol); 5179 if (sock < 0) 5180 continue; 5181 5182 TRACE (TRACE_FUNCTION, " -> Connecting to %s\n", hostname); 5183 if (connect(sock, res->ai_addr, res->ai_addrlen) < 0) { 5184 close(sock); 5185 sock = -1; 5186 continue; 5187 } 5188 break; 5189 } 5190 freeaddrinfo(res0); 5191 return sock; 5192 } 5193 5194 #endif /* defined AUTH_CLIENT_SUPPORT || defined HAVE_KERBEROS 5195 * || defined HAVE_GSSAPI 5196 */ 5197 5198 #endif /* CLIENT_SUPPORT */ 5199