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