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