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