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