1 /* This program is free software; you can redistribute it and/or modify 2 it under the terms of the GNU General Public License as published by 3 the Free Software Foundation; either version 2, or (at your option) 4 any later version. 5 6 This program is distributed in the hope that it will be useful, 7 but WITHOUT ANY WARRANTY; without even the implied warranty of 8 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 GNU General Public License for more details. */ 10 11 #include <assert.h> 12 #include "cvs.h" 13 #include "watch.h" 14 #include "edit.h" 15 #include "fileattr.h" 16 #include "getline.h" 17 #include "buffer.h" 18 19 #ifdef SERVER_SUPPORT 20 21 #ifdef HAVE_WINSOCK_H 22 #include <winsock.h> 23 #endif 24 25 #if defined (AUTH_SERVER_SUPPORT) || defined (HAVE_KERBEROS) || defined (HAVE_GSSAPI) 26 #include <sys/socket.h> 27 #endif 28 29 #ifdef HAVE_KERBEROS 30 # include <netinet/in.h> 31 # include <krb.h> 32 # ifndef HAVE_KRB_GET_ERR_TEXT 33 # define krb_get_err_text(status) krb_err_txt[status] 34 # endif 35 36 /* Information we need if we are going to use Kerberos encryption. */ 37 static C_Block kblock; 38 static Key_schedule sched; 39 40 #endif 41 42 #ifdef HAVE_GSSAPI 43 44 #include <netdb.h> 45 46 #ifdef HAVE_GSSAPI_H 47 #include <gssapi.h> 48 #endif 49 #ifdef HAVE_GSSAPI_GSSAPI_H 50 #include <gssapi/gssapi.h> 51 #endif 52 #ifdef HAVE_GSSAPI_GSSAPI_GENERIC_H 53 #include <gssapi/gssapi_generic.h> 54 #endif 55 56 #ifndef HAVE_GSS_C_NT_HOSTBASED_SERVICE 57 #define GSS_C_NT_HOSTBASED_SERVICE gss_nt_service_name 58 #endif 59 60 /* We use Kerberos 5 routines to map the GSSAPI credential to a user 61 name. */ 62 #include <krb5.h> 63 64 /* We need this to wrap data. */ 65 static gss_ctx_id_t gcontext; 66 67 static void gserver_authenticate_connection PROTO((void)); 68 69 /* Whether we are already wrapping GSSAPI communication. */ 70 static int cvs_gssapi_wrapping; 71 72 # ifdef ENCRYPTION 73 /* Whether to encrypt GSSAPI communication. We use a global variable 74 like this because we use the same buffer type (gssapi_wrap) to 75 handle both authentication and encryption, and we don't want 76 multiple instances of that buffer in the communication stream. */ 77 int cvs_gssapi_encrypt; 78 # endif 79 80 #endif 81 82 /* for select */ 83 #include <sys/types.h> 84 #ifdef HAVE_SYS_BSDTYPES_H 85 #include <sys/bsdtypes.h> 86 #endif 87 88 #if TIME_WITH_SYS_TIME 89 # include <sys/time.h> 90 # include <time.h> 91 #else 92 # if HAVE_SYS_TIME_H 93 # include <sys/time.h> 94 # else 95 # include <time.h> 96 # endif 97 #endif 98 99 #if HAVE_SYS_SELECT_H 100 #include <sys/select.h> 101 #endif 102 103 #ifndef O_NONBLOCK 104 #define O_NONBLOCK O_NDELAY 105 #endif 106 107 /* EWOULDBLOCK is not defined by POSIX, but some BSD systems will 108 return it, rather than EAGAIN, for nonblocking writes. */ 109 #ifdef EWOULDBLOCK 110 #define blocking_error(err) ((err) == EWOULDBLOCK || (err) == EAGAIN) 111 #else 112 #define blocking_error(err) ((err) == EAGAIN) 113 #endif 114 115 #ifdef AUTH_SERVER_SUPPORT 116 #ifdef HAVE_GETSPNAM 117 #include <shadow.h> 118 #endif 119 #endif /* AUTH_SERVER_SUPPORT */ 120 121 /* For initgroups(). */ 122 #if HAVE_INITGROUPS 123 #include <grp.h> 124 #endif /* HAVE_INITGROUPS */ 125 126 #ifdef AUTH_SERVER_SUPPORT 127 128 /* The cvs username sent by the client, which might or might not be 129 the same as the system username the server eventually switches to 130 run as. CVS_Username gets set iff password authentication is 131 successful. */ 132 char *CVS_Username = NULL; 133 134 /* Used to check that same repos is transmitted in pserver auth and in 135 later CVS protocol. Exported because root.c also uses. */ 136 static char *Pserver_Repos = NULL; 137 138 /* Should we check for system usernames/passwords? Can be changed by 139 CVSROOT/config. */ 140 int system_auth = 1; 141 142 #endif /* AUTH_SERVER_SUPPORT */ 143 144 145 /* While processing requests, this buffer accumulates data to be sent to 146 the client, and then once we are in do_cvs_command, we use it 147 for all the data to be sent. */ 148 static struct buffer *buf_to_net; 149 150 /* This buffer is used to read input from the client. */ 151 static struct buffer *buf_from_net; 152 153 /* 154 * This is where we stash stuff we are going to use. Format string 155 * which expects a single directory within it, starting with a slash. 156 */ 157 static char *server_temp_dir; 158 159 /* This is the original value of server_temp_dir, before any possible 160 changes inserted by serve_max_dotdot. */ 161 static char *orig_server_temp_dir; 162 163 /* Nonzero if we should keep the temp directory around after we exit. */ 164 static int dont_delete_temp; 165 166 static void server_write_entries PROTO((void)); 167 168 /* All server communication goes through buffer structures. Most of 169 the buffers are built on top of a file descriptor. This structure 170 is used as the closure field in a buffer. */ 171 172 struct fd_buffer 173 { 174 /* The file descriptor. */ 175 int fd; 176 /* Nonzero if the file descriptor is in blocking mode. */ 177 int blocking; 178 }; 179 180 static struct buffer *fd_buffer_initialize 181 PROTO ((int, int, void (*) (struct buffer *))); 182 static int fd_buffer_input PROTO((void *, char *, int, int, int *)); 183 static int fd_buffer_output PROTO((void *, const char *, int, int *)); 184 static int fd_buffer_flush PROTO((void *)); 185 static int fd_buffer_block PROTO((void *, int)); 186 187 /* Initialize a buffer built on a file descriptor. FD is the file 188 descriptor. INPUT is nonzero if this is for input, zero if this is 189 for output. MEMORY is the function to call when a memory error 190 occurs. */ 191 192 static struct buffer * 193 fd_buffer_initialize (fd, input, memory) 194 int fd; 195 int input; 196 void (*memory) PROTO((struct buffer *)); 197 { 198 struct fd_buffer *n; 199 200 n = (struct fd_buffer *) xmalloc (sizeof *n); 201 n->fd = fd; 202 n->blocking = 1; 203 return buf_initialize (input ? fd_buffer_input : NULL, 204 input ? NULL : fd_buffer_output, 205 input ? NULL : fd_buffer_flush, 206 fd_buffer_block, 207 (int (*) PROTO((void *))) NULL, 208 memory, 209 n); 210 } 211 212 /* The buffer input function for a buffer built on a file descriptor. */ 213 214 static int 215 fd_buffer_input (closure, data, need, size, got) 216 void *closure; 217 char *data; 218 int need; 219 int size; 220 int *got; 221 { 222 struct fd_buffer *fd = (struct fd_buffer *) closure; 223 int nbytes; 224 225 if (! fd->blocking) 226 nbytes = read (fd->fd, data, size); 227 else 228 { 229 /* This case is not efficient. Fortunately, I don't think it 230 ever actually happens. */ 231 nbytes = read (fd->fd, data, need == 0 ? 1 : need); 232 } 233 234 if (nbytes > 0) 235 { 236 *got = nbytes; 237 return 0; 238 } 239 240 *got = 0; 241 242 if (nbytes == 0) 243 { 244 /* End of file. This assumes that we are using POSIX or BSD 245 style nonblocking I/O. On System V we will get a zero 246 return if there is no data, even when not at EOF. */ 247 return -1; 248 } 249 250 /* Some error occurred. */ 251 252 if (blocking_error (errno)) 253 { 254 /* Everything's fine, we just didn't get any data. */ 255 return 0; 256 } 257 258 return errno; 259 } 260 261 /* The buffer output function for a buffer built on a file descriptor. */ 262 263 static int 264 fd_buffer_output (closure, data, have, wrote) 265 void *closure; 266 const char *data; 267 int have; 268 int *wrote; 269 { 270 struct fd_buffer *fd = (struct fd_buffer *) closure; 271 272 *wrote = 0; 273 274 while (have > 0) 275 { 276 int nbytes; 277 278 nbytes = write (fd->fd, data, have); 279 280 if (nbytes <= 0) 281 { 282 if (! fd->blocking 283 && (nbytes == 0 || blocking_error (errno))) 284 { 285 /* A nonblocking write failed to write any data. Just 286 return. */ 287 return 0; 288 } 289 290 /* Some sort of error occurred. */ 291 292 if (nbytes == 0) 293 return EIO; 294 295 return errno; 296 } 297 298 *wrote += nbytes; 299 data += nbytes; 300 have -= nbytes; 301 } 302 303 return 0; 304 } 305 306 /* The buffer flush function for a buffer built on a file descriptor. */ 307 308 /*ARGSUSED*/ 309 static int 310 fd_buffer_flush (closure) 311 void *closure; 312 { 313 /* Nothing to do. File descriptors are always flushed. */ 314 return 0; 315 } 316 317 /* The buffer block function for a buffer built on a file descriptor. */ 318 319 static int 320 fd_buffer_block (closure, block) 321 void *closure; 322 int block; 323 { 324 struct fd_buffer *fd = (struct fd_buffer *) closure; 325 int flags; 326 327 flags = fcntl (fd->fd, F_GETFL, 0); 328 if (flags < 0) 329 return errno; 330 331 if (block) 332 flags &= ~O_NONBLOCK; 333 else 334 flags |= O_NONBLOCK; 335 336 if (fcntl (fd->fd, F_SETFL, flags) < 0) 337 return errno; 338 339 fd->blocking = block; 340 341 return 0; 342 } 343 344 /* Populate all of the directories between BASE_DIR and its relative 345 subdirectory DIR with CVSADM directories. Return 0 for success or 346 errno value. */ 347 static int create_adm_p PROTO((char *, char *)); 348 349 static int 350 create_adm_p (base_dir, dir) 351 char *base_dir; 352 char *dir; 353 { 354 char *dir_where_cvsadm_lives, *dir_to_register, *p, *tmp; 355 int retval, done; 356 FILE *f; 357 358 if (strcmp (dir, ".") == 0) 359 return 0; /* nothing to do */ 360 361 /* Allocate some space for our directory-munging string. */ 362 p = malloc (strlen (dir) + 1); 363 if (p == NULL) 364 return ENOMEM; 365 366 dir_where_cvsadm_lives = malloc (strlen (base_dir) + strlen (dir) + 100); 367 if (dir_where_cvsadm_lives == NULL) 368 return ENOMEM; 369 370 /* Allocate some space for the temporary string in which we will 371 construct filenames. */ 372 tmp = malloc (strlen (base_dir) + strlen (dir) + 100); 373 if (tmp == NULL) 374 return ENOMEM; 375 376 377 /* We make several passes through this loop. On the first pass, 378 we simply create the CVSADM directory in the deepest directory. 379 For each subsequent pass, we try to remove the last path 380 element from DIR, create the CVSADM directory in the remaining 381 pathname, and register the subdirectory in the newly created 382 CVSADM directory. */ 383 384 retval = done = 0; 385 386 strcpy (p, dir); 387 strcpy (dir_where_cvsadm_lives, base_dir); 388 strcat (dir_where_cvsadm_lives, "/"); 389 strcat (dir_where_cvsadm_lives, p); 390 dir_to_register = NULL; 391 392 while (1) 393 { 394 /* Create CVSADM. */ 395 (void) sprintf (tmp, "%s/%s", dir_where_cvsadm_lives, CVSADM); 396 if ((CVS_MKDIR (tmp, 0777) < 0) && (errno != EEXIST)) 397 { 398 retval = errno; 399 goto finish; 400 } 401 402 /* Create CVSADM_REP. */ 403 (void) sprintf (tmp, "%s/%s", dir_where_cvsadm_lives, CVSADM_REP); 404 if (! isfile (tmp)) 405 { 406 /* Use Emptydir as the placeholder until the client sends 407 us the real value. This code is similar to checkout.c 408 (emptydir_name), but the code below returns errors 409 differently. */ 410 411 char *empty; 412 empty = malloc (strlen (CVSroot_directory) 413 + sizeof (CVSROOTADM) 414 + sizeof (CVSNULLREPOS) 415 + 10); 416 if (! empty) 417 { 418 retval = ENOMEM; 419 goto finish; 420 } 421 422 /* Create the directory name. */ 423 (void) sprintf (empty, "%s/%s/%s", CVSroot_directory, 424 CVSROOTADM, CVSNULLREPOS); 425 426 /* Create the directory if it doesn't exist. */ 427 if (! isfile (empty)) 428 { 429 mode_t omask; 430 omask = umask (cvsumask); 431 if (CVS_MKDIR (empty, 0777) < 0) 432 { 433 retval = errno; 434 free (empty); 435 goto finish; 436 } 437 (void) umask (omask); 438 } 439 440 441 f = CVS_FOPEN (tmp, "w"); 442 if (f == NULL) 443 { 444 retval = errno; 445 free (empty); 446 goto finish; 447 } 448 /* Write the directory name to CVSADM_REP. */ 449 if (fprintf (f, "%s\n", empty) < 0) 450 { 451 retval = errno; 452 fclose (f); 453 free (empty); 454 goto finish; 455 } 456 if (fclose (f) == EOF) 457 { 458 retval = errno; 459 free (empty); 460 goto finish; 461 } 462 463 /* Clean up after ourselves. */ 464 free (empty); 465 } 466 467 /* Create CVSADM_ENT. We open in append mode because we 468 don't want to clobber an existing Entries file. */ 469 (void) sprintf (tmp, "%s/%s", dir_where_cvsadm_lives, CVSADM_ENT); 470 f = CVS_FOPEN (tmp, "a"); 471 if (f == NULL) 472 { 473 retval = errno; 474 goto finish; 475 } 476 if (fclose (f) == EOF) 477 { 478 retval = errno; 479 goto finish; 480 } 481 482 if (dir_to_register != NULL) 483 { 484 /* FIXME: Yes, this results in duplicate entries in the 485 Entries.Log file, but it doesn't currently matter. We 486 might need to change this later on to make sure that we 487 only write one entry. */ 488 489 Subdir_Register ((List *) NULL, dir_where_cvsadm_lives, 490 dir_to_register); 491 } 492 493 if (done) 494 break; 495 496 dir_to_register = strrchr (p, '/'); 497 if (dir_to_register == NULL) 498 { 499 dir_to_register = p; 500 strcpy (dir_where_cvsadm_lives, base_dir); 501 done = 1; 502 } 503 else 504 { 505 *dir_to_register = '\0'; 506 dir_to_register++; 507 strcpy (dir_where_cvsadm_lives, base_dir); 508 strcat (dir_where_cvsadm_lives, "/"); 509 strcat (dir_where_cvsadm_lives, p); 510 } 511 } 512 513 finish: 514 free (tmp); 515 free (dir_where_cvsadm_lives); 516 free (p); 517 return retval; 518 } 519 520 /* 521 * Make directory DIR, including all intermediate directories if necessary. 522 * Returns 0 for success or errno code. 523 */ 524 static int mkdir_p PROTO((char *)); 525 526 static int 527 mkdir_p (dir) 528 char *dir; 529 { 530 char *p; 531 char *q = malloc (strlen (dir) + 1); 532 int retval; 533 534 if (q == NULL) 535 return ENOMEM; 536 537 retval = 0; 538 539 /* 540 * Skip over leading slash if present. We won't bother to try to 541 * make '/'. 542 */ 543 p = dir + 1; 544 while (1) 545 { 546 while (*p != '/' && *p != '\0') 547 ++p; 548 if (*p == '/') 549 { 550 strncpy (q, dir, p - dir); 551 q[p - dir] = '\0'; 552 if (q[p - dir - 1] != '/' && CVS_MKDIR (q, 0777) < 0) 553 { 554 int saved_errno = errno; 555 556 if (saved_errno != EEXIST 557 && ((saved_errno != EACCES && saved_errno != EROFS) 558 || !isdir (q))) 559 { 560 retval = saved_errno; 561 goto done; 562 } 563 } 564 ++p; 565 } 566 else 567 { 568 if (CVS_MKDIR (dir, 0777) < 0) 569 retval = errno; 570 goto done; 571 } 572 } 573 done: 574 free (q); 575 return retval; 576 } 577 578 /* 579 * Print the error response for error code STATUS. The caller is 580 * reponsible for making sure we get back to the command loop without 581 * any further output occuring. 582 * Must be called only in contexts where it is OK to send output. 583 */ 584 static void 585 print_error (status) 586 int status; 587 { 588 char *msg; 589 buf_output0 (buf_to_net, "error "); 590 msg = strerror (status); 591 if (msg) 592 buf_output0 (buf_to_net, msg); 593 buf_append_char (buf_to_net, '\n'); 594 595 buf_flush (buf_to_net, 0); 596 } 597 598 static int pending_error; 599 /* 600 * Malloc'd text for pending error. Each line must start with "E ". The 601 * last line should not end with a newline. 602 */ 603 static char *pending_error_text; 604 605 /* If an error is pending, print it and return 1. If not, return 0. 606 Must be called only in contexts where it is OK to send output. */ 607 static int 608 print_pending_error () 609 { 610 if (pending_error_text) 611 { 612 buf_output0 (buf_to_net, pending_error_text); 613 buf_append_char (buf_to_net, '\n'); 614 if (pending_error) 615 print_error (pending_error); 616 else 617 buf_output0 (buf_to_net, "error \n"); 618 619 buf_flush (buf_to_net, 0); 620 621 pending_error = 0; 622 free (pending_error_text); 623 pending_error_text = NULL; 624 return 1; 625 } 626 else if (pending_error) 627 { 628 print_error (pending_error); 629 pending_error = 0; 630 return 1; 631 } 632 else 633 return 0; 634 } 635 636 /* Is an error pending? */ 637 #define error_pending() (pending_error || pending_error_text) 638 639 static int alloc_pending PROTO ((size_t size)); 640 641 /* Allocate SIZE bytes for pending_error_text and return nonzero 642 if we could do it. */ 643 static int 644 alloc_pending (size) 645 size_t size; 646 { 647 if (error_pending ()) 648 /* Probably alloc_pending callers will have already checked for 649 this case. But we might as well handle it if they don't, I 650 guess. */ 651 return 0; 652 pending_error_text = malloc (size); 653 if (pending_error_text == NULL) 654 { 655 pending_error = ENOMEM; 656 return 0; 657 } 658 return 1; 659 } 660 661 static void serve_is_modified PROTO ((char *)); 662 663 static int supported_response PROTO ((char *)); 664 665 static int 666 supported_response (name) 667 char *name; 668 { 669 struct response *rs; 670 671 for (rs = responses; rs->name != NULL; ++rs) 672 if (strcmp (rs->name, name) == 0) 673 return rs->status == rs_supported; 674 error (1, 0, "internal error: testing support for unknown response?"); 675 /* NOTREACHED */ 676 return 0; 677 } 678 679 static void 680 serve_valid_responses (arg) 681 char *arg; 682 { 683 char *p = arg; 684 char *q; 685 struct response *rs; 686 do 687 { 688 q = strchr (p, ' '); 689 if (q != NULL) 690 *q++ = '\0'; 691 for (rs = responses; rs->name != NULL; ++rs) 692 { 693 if (strcmp (rs->name, p) == 0) 694 break; 695 } 696 if (rs->name == NULL) 697 /* 698 * It is a response we have never heard of (and thus never 699 * will want to use). So don't worry about it. 700 */ 701 ; 702 else 703 rs->status = rs_supported; 704 p = q; 705 } while (q != NULL); 706 for (rs = responses; rs->name != NULL; ++rs) 707 { 708 if (rs->status == rs_essential) 709 { 710 buf_output0 (buf_to_net, "E response `"); 711 buf_output0 (buf_to_net, rs->name); 712 buf_output0 (buf_to_net, "' not supported by client\nerror \n"); 713 714 /* FIXME: This call to buf_flush could conceivably 715 cause deadlock, as noted in server_cleanup. */ 716 buf_flush (buf_to_net, 1); 717 718 /* I'm doing this manually rather than via error_exit () 719 because I'm not sure whether we want to call server_cleanup. 720 Needs more investigation.... */ 721 722 #ifdef SYSTEM_CLEANUP 723 /* Hook for OS-specific behavior, for example socket subsystems on 724 NT and OS2 or dealing with windows and arguments on Mac. */ 725 SYSTEM_CLEANUP (); 726 #endif 727 728 exit (EXIT_FAILURE); 729 } 730 else if (rs->status == rs_optional) 731 rs->status = rs_not_supported; 732 } 733 } 734 735 static void 736 serve_root (arg) 737 char *arg; 738 { 739 char *env; 740 char *path; 741 int save_errno; 742 char *arg_dup; 743 744 if (error_pending()) return; 745 746 if (!isabsolute (arg)) 747 { 748 if (alloc_pending (80 + strlen (arg))) 749 sprintf (pending_error_text, 750 "E Root %s must be an absolute pathname", arg); 751 return; 752 } 753 754 /* Sending "Root" twice is illegal. 755 756 The other way to handle a duplicate Root requests would be as a 757 request to clear out all state and start over as if it was a 758 new connection. Doing this would cause interoperability 759 headaches, so it should be a different request, if there is 760 any reason why such a feature is needed. */ 761 if (CVSroot_directory != NULL) 762 { 763 if (alloc_pending (80 + strlen (arg))) 764 sprintf (pending_error_text, 765 "E Protocol error: Duplicate Root request, for %s", arg); 766 return; 767 } 768 769 #ifdef AUTH_SERVER_SUPPORT 770 if (Pserver_Repos != NULL) 771 { 772 if (strcmp (Pserver_Repos, arg) != 0) 773 { 774 if (alloc_pending (80 + strlen (Pserver_Repos) + strlen (arg))) 775 /* The explicitness is to aid people who are writing clients. 776 I don't see how this information could help an 777 attacker. */ 778 sprintf (pending_error_text, "\ 779 E Protocol error: Root says \"%s\" but pserver says \"%s\"", 780 arg, Pserver_Repos); 781 } 782 } 783 #endif 784 arg_dup = malloc (strlen (arg) + 1); 785 if (arg_dup == NULL) 786 { 787 pending_error = ENOMEM; 788 return; 789 } 790 strcpy (arg_dup, arg); 791 set_local_cvsroot (arg_dup); 792 793 /* For pserver, this will already have happened, and the call will do 794 nothing. But for rsh, we need to do it now. */ 795 parse_config (CVSroot_directory); 796 797 path = malloc (strlen (CVSroot_directory) 798 + sizeof (CVSROOTADM) 799 + sizeof (CVSROOTADM_HISTORY) 800 + 10); 801 if (path == NULL) 802 { 803 pending_error = ENOMEM; 804 return; 805 } 806 (void) sprintf (path, "%s/%s", CVSroot_directory, CVSROOTADM); 807 if (!isaccessible (path, R_OK | X_OK)) 808 { 809 save_errno = errno; 810 pending_error_text = malloc (80 + strlen (path)); 811 if (pending_error_text != NULL) 812 sprintf (pending_error_text, "E Cannot access %s", path); 813 pending_error = save_errno; 814 } 815 (void) strcat (path, "/"); 816 (void) strcat (path, CVSROOTADM_HISTORY); 817 if (readonlyfs == 0 && isfile (path) && !isaccessible (path, R_OK | W_OK)) 818 { 819 save_errno = errno; 820 pending_error_text = malloc (80 + strlen (path)); 821 if (pending_error_text != NULL) 822 sprintf (pending_error_text, "E \ 823 Sorry, you don't have read/write access to the history file %s", path); 824 pending_error = save_errno; 825 } 826 free (path); 827 828 #ifdef HAVE_PUTENV 829 env = malloc (strlen (CVSROOT_ENV) + strlen (CVSroot_directory) + 1 + 1); 830 if (env == NULL) 831 { 832 pending_error = ENOMEM; 833 return; 834 } 835 (void) sprintf (env, "%s=%s", CVSROOT_ENV, CVSroot_directory); 836 (void) putenv (env); 837 /* do not free env, as putenv has control of it */ 838 #endif 839 } 840 841 static int max_dotdot_limit = 0; 842 843 /* Is this pathname OK to recurse into when we are running as the server? 844 If not, call error() with a fatal error. */ 845 void 846 server_pathname_check (path) 847 char *path; 848 { 849 /* An absolute pathname is almost surely a path on the *client* machine, 850 and is unlikely to do us any good here. It also is probably capable 851 of being a security hole in the anonymous readonly case. */ 852 if (isabsolute (path)) 853 /* Giving an error is actually kind of a cop-out, in the sense 854 that it would be nice for "cvs co -d /foo/bar/baz" to work. 855 A quick fix in the server would be requiring Max-dotdot of 856 at least one if pathnames are absolute, and then putting 857 /abs/foo/bar/baz in the temp dir beside the /d/d/d stuff. 858 A cleaner fix in the server might be to decouple the 859 pathnames we pass back to the client from pathnames in our 860 temp directory (this would also probably remove the need 861 for Max-dotdot). A fix in the client would have the client 862 turn it into "cd /foo/bar; cvs co -d baz" (more or less). 863 This probably has some problems with pathnames which appear 864 in messages. */ 865 error (1, 0, "absolute pathname `%s' illegal for server", path); 866 if (pathname_levels (path) > max_dotdot_limit) 867 { 868 /* Similar to the isabsolute case in security implications. */ 869 error (0, 0, "protocol error: `%s' contains more leading ..", path); 870 error (1, 0, "than the %d which Max-dotdot specified", 871 max_dotdot_limit); 872 } 873 } 874 875 static int outside_root PROTO ((char *)); 876 877 /* Is file or directory REPOS an absolute pathname within the 878 CVSroot_directory? If yes, return 0. If no, set pending_error 879 and return 1. */ 880 static int 881 outside_root (repos) 882 char *repos; 883 { 884 size_t repos_len = strlen (repos); 885 size_t root_len = strlen (CVSroot_directory); 886 887 /* I think isabsolute (repos) should always be true, and that 888 any RELATIVE_REPOS stuff should only be in CVS/Repository 889 files, not the protocol (for compatibility), but I'm putting 890 in the isabsolute check just in case. */ 891 if (!isabsolute (repos)) 892 { 893 if (alloc_pending (repos_len + 80)) 894 sprintf (pending_error_text, "\ 895 E protocol error: %s is not absolute", repos); 896 return 1; 897 } 898 899 if (repos_len < root_len 900 || strncmp (CVSroot_directory, repos, root_len) != 0) 901 { 902 not_within: 903 if (alloc_pending (strlen (CVSroot_directory) 904 + strlen (repos) 905 + 80)) 906 sprintf (pending_error_text, "\ 907 E protocol error: directory '%s' not within root '%s'", 908 repos, CVSroot_directory); 909 return 1; 910 } 911 if (repos_len > root_len) 912 { 913 if (repos[root_len] != '/') 914 goto not_within; 915 if (pathname_levels (repos + root_len + 1) > 0) 916 goto not_within; 917 } 918 return 0; 919 } 920 921 static int outside_dir PROTO ((char *)); 922 923 /* Is file or directory FILE outside the current directory (that is, does 924 it contain '/')? If no, return 0. If yes, set pending_error 925 and return 1. */ 926 static int 927 outside_dir (file) 928 char *file; 929 { 930 if (strchr (file, '/') != NULL) 931 { 932 if (alloc_pending (strlen (file) 933 + 80)) 934 sprintf (pending_error_text, "\ 935 E protocol error: directory '%s' not within current directory", 936 file); 937 return 1; 938 } 939 return 0; 940 } 941 942 /* 943 * Add as many directories to the temp directory as the client tells us it 944 * will use "..", so we never try to access something outside the temp 945 * directory via "..". 946 */ 947 static void 948 serve_max_dotdot (arg) 949 char *arg; 950 { 951 int lim = atoi (arg); 952 int i; 953 char *p; 954 955 if (lim < 0) 956 return; 957 p = malloc (strlen (server_temp_dir) + 2 * lim + 10); 958 if (p == NULL) 959 { 960 pending_error = ENOMEM; 961 return; 962 } 963 strcpy (p, server_temp_dir); 964 for (i = 0; i < lim; ++i) 965 strcat (p, "/d"); 966 if (server_temp_dir != orig_server_temp_dir) 967 free (server_temp_dir); 968 server_temp_dir = p; 969 max_dotdot_limit = lim; 970 } 971 972 static char *dir_name; 973 974 static void 975 dirswitch (dir, repos) 976 char *dir; 977 char *repos; 978 { 979 int status; 980 FILE *f; 981 size_t dir_len; 982 983 server_write_entries (); 984 985 if (error_pending()) return; 986 987 /* Check for bad directory name. 988 989 FIXME: could/should unify these checks with server_pathname_check 990 except they need to report errors differently. */ 991 if (isabsolute (dir)) 992 { 993 if (alloc_pending (80 + strlen (dir))) 994 sprintf (pending_error_text, 995 "E absolute pathname `%s' illegal for server", dir); 996 return; 997 } 998 if (pathname_levels (dir) > max_dotdot_limit) 999 { 1000 if (alloc_pending (80 + strlen (dir))) 1001 sprintf (pending_error_text, 1002 "E protocol error: `%s' has too many ..", dir); 1003 return; 1004 } 1005 1006 if (dir_name != NULL) 1007 free (dir_name); 1008 1009 dir_len = strlen (dir); 1010 1011 /* Check for a trailing '/'. This is not ISDIRSEP because \ in the 1012 protocol is an ordinary character, not a directory separator (of 1013 course, it is perhaps unwise to use it in directory names, but that 1014 is another issue). */ 1015 if (dir_len > 0 1016 && dir[dir_len - 1] == '/') 1017 { 1018 if (alloc_pending (80 + dir_len)) 1019 sprintf (pending_error_text, 1020 "E protocol error: invalid directory syntax in %s", dir); 1021 return; 1022 } 1023 1024 dir_name = malloc (strlen (server_temp_dir) + dir_len + 40); 1025 if (dir_name == NULL) 1026 { 1027 pending_error = ENOMEM; 1028 return; 1029 } 1030 1031 strcpy (dir_name, server_temp_dir); 1032 strcat (dir_name, "/"); 1033 strcat (dir_name, dir); 1034 1035 status = mkdir_p (dir_name); 1036 if (status != 0 1037 && status != EEXIST) 1038 { 1039 pending_error = status; 1040 if (alloc_pending (80 + strlen (dir_name))) 1041 sprintf (pending_error_text, "E cannot mkdir %s", dir_name); 1042 return; 1043 } 1044 1045 /* We need to create adm directories in all path elements because 1046 we want the server to descend them, even if the client hasn't 1047 sent the appropriate "Argument xxx" command to match the 1048 already-sent "Directory xxx" command. See recurse.c 1049 (start_recursion) for a big discussion of this. */ 1050 1051 status = create_adm_p (server_temp_dir, dir); 1052 if (status != 0) 1053 { 1054 pending_error = status; 1055 if (alloc_pending (80 + strlen (dir_name))) 1056 sprintf (pending_error_text, "E cannot create_adm_p %s", dir_name); 1057 return; 1058 } 1059 1060 if ( CVS_CHDIR (dir_name) < 0) 1061 { 1062 pending_error = errno; 1063 if (alloc_pending (80 + strlen (dir_name))) 1064 sprintf (pending_error_text, "E cannot change to %s", dir_name); 1065 return; 1066 } 1067 /* 1068 * This is pretty much like calling Create_Admin, but Create_Admin doesn't 1069 * report errors in the right way for us. 1070 */ 1071 if ((CVS_MKDIR (CVSADM, 0777) < 0) && (errno != EEXIST)) 1072 { 1073 pending_error = errno; 1074 return; 1075 } 1076 1077 /* The following will overwrite the contents of CVSADM_REP. This 1078 is the correct behavior -- mkdir_p may have written a 1079 placeholder value to this file and we need to insert the 1080 correct value. */ 1081 1082 f = CVS_FOPEN (CVSADM_REP, "w"); 1083 if (f == NULL) 1084 { 1085 pending_error = errno; 1086 return; 1087 } 1088 if (fprintf (f, "%s", repos) < 0) 1089 { 1090 pending_error = errno; 1091 fclose (f); 1092 return; 1093 } 1094 /* Non-remote CVS handles a module representing the entire tree 1095 (e.g., an entry like ``world -a .'') by putting /. at the end 1096 of the Repository file, so we do the same. */ 1097 if (strcmp (dir, ".") == 0 1098 && CVSroot_directory != NULL 1099 && strcmp (CVSroot_directory, repos) == 0) 1100 { 1101 if (fprintf (f, "/.") < 0) 1102 { 1103 pending_error = errno; 1104 fclose (f); 1105 return; 1106 } 1107 } 1108 if (fprintf (f, "\n") < 0) 1109 { 1110 pending_error = errno; 1111 fclose (f); 1112 return; 1113 } 1114 if (fclose (f) == EOF) 1115 { 1116 pending_error = errno; 1117 return; 1118 } 1119 /* We open in append mode because we don't want to clobber an 1120 existing Entries file. */ 1121 f = CVS_FOPEN (CVSADM_ENT, "a"); 1122 if (f == NULL) 1123 { 1124 pending_error = errno; 1125 if (alloc_pending (80 + strlen (CVSADM_ENT))) 1126 sprintf (pending_error_text, "E cannot open %s", CVSADM_ENT); 1127 return; 1128 } 1129 if (fclose (f) == EOF) 1130 { 1131 pending_error = errno; 1132 if (alloc_pending (80 + strlen (CVSADM_ENT))) 1133 sprintf (pending_error_text, "E cannot close %s", CVSADM_ENT); 1134 return; 1135 } 1136 } 1137 1138 static void 1139 serve_repository (arg) 1140 char *arg; 1141 { 1142 pending_error_text = malloc (80); 1143 if (pending_error_text == NULL) 1144 pending_error = ENOMEM; 1145 else 1146 strcpy (pending_error_text, 1147 "E Repository request is obsolete; aborted"); 1148 return; 1149 } 1150 1151 static void 1152 serve_directory (arg) 1153 char *arg; 1154 { 1155 int status; 1156 char *repos; 1157 1158 status = buf_read_line (buf_from_net, &repos, (int *) NULL); 1159 if (status == 0) 1160 { 1161 if (outside_root (repos)) 1162 return; 1163 dirswitch (arg, repos); 1164 free (repos); 1165 } 1166 else if (status == -2) 1167 { 1168 pending_error = ENOMEM; 1169 } 1170 else 1171 { 1172 pending_error_text = malloc (80 + strlen (arg)); 1173 if (pending_error_text == NULL) 1174 { 1175 pending_error = ENOMEM; 1176 } 1177 else if (status == -1) 1178 { 1179 sprintf (pending_error_text, 1180 "E end of file reading mode for %s", arg); 1181 } 1182 else 1183 { 1184 sprintf (pending_error_text, 1185 "E error reading mode for %s", arg); 1186 pending_error = status; 1187 } 1188 } 1189 } 1190 1191 static void 1192 serve_static_directory (arg) 1193 char *arg; 1194 { 1195 FILE *f; 1196 1197 if (error_pending ()) return; 1198 1199 f = CVS_FOPEN (CVSADM_ENTSTAT, "w+"); 1200 if (f == NULL) 1201 { 1202 pending_error = errno; 1203 if (alloc_pending (80 + strlen (CVSADM_ENTSTAT))) 1204 sprintf (pending_error_text, "E cannot open %s", CVSADM_ENTSTAT); 1205 return; 1206 } 1207 if (fclose (f) == EOF) 1208 { 1209 pending_error = errno; 1210 if (alloc_pending (80 + strlen (CVSADM_ENTSTAT))) 1211 sprintf (pending_error_text, "E cannot close %s", CVSADM_ENTSTAT); 1212 return; 1213 } 1214 } 1215 1216 static void 1217 serve_sticky (arg) 1218 char *arg; 1219 { 1220 FILE *f; 1221 1222 if (error_pending ()) return; 1223 1224 f = CVS_FOPEN (CVSADM_TAG, "w+"); 1225 if (f == NULL) 1226 { 1227 pending_error = errno; 1228 if (alloc_pending (80 + strlen (CVSADM_TAG))) 1229 sprintf (pending_error_text, "E cannot open %s", CVSADM_TAG); 1230 return; 1231 } 1232 if (fprintf (f, "%s\n", arg) < 0) 1233 { 1234 pending_error = errno; 1235 if (alloc_pending (80 + strlen (CVSADM_TAG))) 1236 sprintf (pending_error_text, "E cannot write to %s", CVSADM_TAG); 1237 return; 1238 } 1239 if (fclose (f) == EOF) 1240 { 1241 pending_error = errno; 1242 if (alloc_pending (80 + strlen (CVSADM_TAG))) 1243 sprintf (pending_error_text, "E cannot close %s", CVSADM_TAG); 1244 return; 1245 } 1246 } 1247 1248 /* 1249 * Read SIZE bytes from buf_from_net, write them to FILE. 1250 * 1251 * Currently this isn't really used for receiving parts of a file -- 1252 * the file is still sent over in one chunk. But if/when we get 1253 * spiffy in-process gzip support working, perhaps the compressed 1254 * pieces could be sent over as they're ready, if the network is fast 1255 * enough. Or something. 1256 */ 1257 static void 1258 receive_partial_file (size, file) 1259 int size; 1260 int file; 1261 { 1262 while (size > 0) 1263 { 1264 int status, nread; 1265 char *data; 1266 1267 status = buf_read_data (buf_from_net, size, &data, &nread); 1268 if (status != 0) 1269 { 1270 if (status == -2) 1271 pending_error = ENOMEM; 1272 else 1273 { 1274 pending_error_text = malloc (80); 1275 if (pending_error_text == NULL) 1276 pending_error = ENOMEM; 1277 else if (status == -1) 1278 { 1279 sprintf (pending_error_text, 1280 "E premature end of file from client"); 1281 pending_error = 0; 1282 } 1283 else 1284 { 1285 sprintf (pending_error_text, 1286 "E error reading from client"); 1287 pending_error = status; 1288 } 1289 } 1290 return; 1291 } 1292 1293 size -= nread; 1294 1295 while (nread > 0) 1296 { 1297 int nwrote; 1298 1299 nwrote = write (file, data, nread); 1300 if (nwrote < 0) 1301 { 1302 pending_error_text = malloc (40); 1303 if (pending_error_text != NULL) 1304 sprintf (pending_error_text, "E unable to write"); 1305 pending_error = errno; 1306 1307 /* Read and discard the file data. */ 1308 while (size > 0) 1309 { 1310 int status, nread; 1311 char *data; 1312 1313 status = buf_read_data (buf_from_net, size, &data, &nread); 1314 if (status != 0) 1315 return; 1316 size -= nread; 1317 } 1318 1319 return; 1320 } 1321 nread -= nwrote; 1322 data += nwrote; 1323 } 1324 } 1325 } 1326 1327 /* Receive SIZE bytes, write to filename FILE. */ 1328 static void 1329 receive_file (size, file, gzipped) 1330 int size; 1331 char *file; 1332 int gzipped; 1333 { 1334 int fd; 1335 char *arg = file; 1336 1337 /* Write the file. */ 1338 fd = CVS_OPEN (arg, O_WRONLY | O_CREAT | O_TRUNC, 0600); 1339 if (fd < 0) 1340 { 1341 pending_error_text = malloc (40 + strlen (arg)); 1342 if (pending_error_text) 1343 sprintf (pending_error_text, "E cannot open %s", arg); 1344 pending_error = errno; 1345 return; 1346 } 1347 1348 if (gzipped) 1349 { 1350 /* Using gunzip_and_write isn't really a high-performance 1351 approach, because it keeps the whole thing in memory 1352 (contiguous memory, worse yet). But it seems easier to 1353 code than the alternative (and less vulnerable to subtle 1354 bugs). Given that this feature is mainly for 1355 compatibility, that is the better tradeoff. */ 1356 1357 int toread = size; 1358 char *filebuf; 1359 char *p; 1360 1361 filebuf = malloc (size); 1362 p = filebuf; 1363 /* If NULL, we still want to read the data and discard it. */ 1364 1365 while (toread > 0) 1366 { 1367 int status, nread; 1368 char *data; 1369 1370 status = buf_read_data (buf_from_net, toread, &data, &nread); 1371 if (status != 0) 1372 { 1373 if (status == -2) 1374 pending_error = ENOMEM; 1375 else 1376 { 1377 pending_error_text = malloc (80); 1378 if (pending_error_text == NULL) 1379 pending_error = ENOMEM; 1380 else if (status == -1) 1381 { 1382 sprintf (pending_error_text, 1383 "E premature end of file from client"); 1384 pending_error = 0; 1385 } 1386 else 1387 { 1388 sprintf (pending_error_text, 1389 "E error reading from client"); 1390 pending_error = status; 1391 } 1392 } 1393 return; 1394 } 1395 1396 toread -= nread; 1397 1398 if (filebuf != NULL) 1399 { 1400 memcpy (p, data, nread); 1401 p += nread; 1402 } 1403 } 1404 if (filebuf == NULL) 1405 { 1406 pending_error = ENOMEM; 1407 goto out; 1408 } 1409 1410 if (gunzip_and_write (fd, file, filebuf, size)) 1411 { 1412 if (alloc_pending (80)) 1413 sprintf (pending_error_text, 1414 "E aborting due to compression error"); 1415 } 1416 free (filebuf); 1417 } 1418 else 1419 receive_partial_file (size, fd); 1420 1421 if (pending_error_text) 1422 { 1423 char *p = realloc (pending_error_text, 1424 strlen (pending_error_text) + strlen (arg) + 30); 1425 if (p) 1426 { 1427 pending_error_text = p; 1428 sprintf (p + strlen (p), ", file %s", arg); 1429 } 1430 /* else original string is supposed to be unchanged */ 1431 } 1432 1433 out: 1434 if (close (fd) < 0 && !error_pending ()) 1435 { 1436 pending_error_text = malloc (40 + strlen (arg)); 1437 if (pending_error_text) 1438 sprintf (pending_error_text, "E cannot close %s", arg); 1439 pending_error = errno; 1440 return; 1441 } 1442 } 1443 1444 /* Kopt for the next file sent in Modified or Is-modified. */ 1445 static char *kopt; 1446 1447 /* Timestamp (Checkin-time) for next file sent in Modified or 1448 Is-modified. */ 1449 static int checkin_time_valid; 1450 static time_t checkin_time; 1451 1452 static void serve_modified PROTO ((char *)); 1453 1454 static void 1455 serve_modified (arg) 1456 char *arg; 1457 { 1458 int size, status; 1459 char *size_text; 1460 char *mode_text; 1461 1462 int gzipped = 0; 1463 1464 /* 1465 * This used to return immediately if error_pending () was true. 1466 * However, that fails, because it causes each line of the file to 1467 * be echoed back to the client as an unrecognized command. The 1468 * client isn't reading from the socket, so eventually both 1469 * processes block trying to write to the other. Now, we try to 1470 * read the file if we can. 1471 */ 1472 1473 status = buf_read_line (buf_from_net, &mode_text, (int *) NULL); 1474 if (status != 0) 1475 { 1476 if (status == -2) 1477 pending_error = ENOMEM; 1478 else 1479 { 1480 pending_error_text = malloc (80 + strlen (arg)); 1481 if (pending_error_text == NULL) 1482 pending_error = ENOMEM; 1483 else 1484 { 1485 if (status == -1) 1486 sprintf (pending_error_text, 1487 "E end of file reading mode for %s", arg); 1488 else 1489 { 1490 sprintf (pending_error_text, 1491 "E error reading mode for %s", arg); 1492 pending_error = status; 1493 } 1494 } 1495 } 1496 return; 1497 } 1498 1499 status = buf_read_line (buf_from_net, &size_text, (int *) NULL); 1500 if (status != 0) 1501 { 1502 if (status == -2) 1503 pending_error = ENOMEM; 1504 else 1505 { 1506 pending_error_text = malloc (80 + strlen (arg)); 1507 if (pending_error_text == NULL) 1508 pending_error = ENOMEM; 1509 else 1510 { 1511 if (status == -1) 1512 sprintf (pending_error_text, 1513 "E end of file reading size for %s", arg); 1514 else 1515 { 1516 sprintf (pending_error_text, 1517 "E error reading size for %s", arg); 1518 pending_error = errno; 1519 } 1520 } 1521 } 1522 return; 1523 } 1524 if (size_text[0] == 'z') 1525 { 1526 gzipped = 1; 1527 size = atoi (size_text + 1); 1528 } 1529 else 1530 size = atoi (size_text); 1531 free (size_text); 1532 1533 if (error_pending ()) 1534 { 1535 /* Now that we know the size, read and discard the file data. */ 1536 while (size > 0) 1537 { 1538 int status, nread; 1539 char *data; 1540 1541 status = buf_read_data (buf_from_net, size, &data, &nread); 1542 if (status != 0) 1543 return; 1544 size -= nread; 1545 } 1546 return; 1547 } 1548 1549 if (outside_dir (arg)) 1550 return; 1551 1552 if (size >= 0) 1553 { 1554 receive_file (size, arg, gzipped); 1555 if (error_pending ()) return; 1556 } 1557 1558 if (checkin_time_valid) 1559 { 1560 struct utimbuf t; 1561 1562 memset (&t, 0, sizeof (t)); 1563 t.modtime = t.actime = checkin_time; 1564 if (utime (arg, &t) < 0) 1565 { 1566 pending_error = errno; 1567 if (alloc_pending (80 + strlen (arg))) 1568 sprintf (pending_error_text, "E cannot utime %s", arg); 1569 return; 1570 } 1571 checkin_time_valid = 0; 1572 } 1573 1574 { 1575 int status = change_mode (arg, mode_text, 0); 1576 free (mode_text); 1577 if (status) 1578 { 1579 pending_error_text = malloc (40 + strlen (arg)); 1580 if (pending_error_text) 1581 sprintf (pending_error_text, 1582 "E cannot change mode for %s", arg); 1583 pending_error = status; 1584 return; 1585 } 1586 } 1587 1588 /* Make sure that the Entries indicate the right kopt. We probably 1589 could do this even in the non-kopt case and, I think, save a stat() 1590 call in time_stamp_server. But for conservatism I'm leaving the 1591 non-kopt case alone. */ 1592 if (kopt != NULL) 1593 serve_is_modified (arg); 1594 } 1595 1596 1597 static void 1598 serve_enable_unchanged (arg) 1599 char *arg; 1600 { 1601 } 1602 1603 struct an_entry { 1604 struct an_entry *next; 1605 char *entry; 1606 }; 1607 1608 static struct an_entry *entries; 1609 1610 static void serve_unchanged PROTO ((char *)); 1611 1612 static void 1613 serve_unchanged (arg) 1614 char *arg; 1615 { 1616 struct an_entry *p; 1617 char *name; 1618 char *cp; 1619 char *timefield; 1620 1621 if (error_pending ()) 1622 return; 1623 1624 if (outside_dir (arg)) 1625 return; 1626 1627 /* Rewrite entries file to have `=' in timestamp field. */ 1628 for (p = entries; p != NULL; p = p->next) 1629 { 1630 name = p->entry + 1; 1631 cp = strchr (name, '/'); 1632 if (cp != NULL 1633 && strlen (arg) == cp - name 1634 && strncmp (arg, name, cp - name) == 0) 1635 { 1636 timefield = strchr (cp + 1, '/') + 1; 1637 if (*timefield != '=') 1638 { 1639 cp = timefield + strlen (timefield); 1640 cp[1] = '\0'; 1641 while (cp > timefield) 1642 { 1643 *cp = cp[-1]; 1644 --cp; 1645 } 1646 *timefield = '='; 1647 } 1648 break; 1649 } 1650 } 1651 } 1652 1653 static void 1654 serve_is_modified (arg) 1655 char *arg; 1656 { 1657 struct an_entry *p; 1658 char *name; 1659 char *cp; 1660 char *timefield; 1661 /* Have we found this file in "entries" yet. */ 1662 int found; 1663 1664 if (error_pending ()) 1665 return; 1666 1667 if (outside_dir (arg)) 1668 return; 1669 1670 /* Rewrite entries file to have `M' in timestamp field. */ 1671 found = 0; 1672 for (p = entries; p != NULL; p = p->next) 1673 { 1674 name = p->entry + 1; 1675 cp = strchr (name, '/'); 1676 if (cp != NULL 1677 && strlen (arg) == cp - name 1678 && strncmp (arg, name, cp - name) == 0) 1679 { 1680 timefield = strchr (cp + 1, '/') + 1; 1681 if (!(timefield[0] == 'M' && timefield[1] == '/')) 1682 { 1683 cp = timefield + strlen (timefield); 1684 cp[1] = '\0'; 1685 while (cp > timefield) 1686 { 1687 *cp = cp[-1]; 1688 --cp; 1689 } 1690 *timefield = 'M'; 1691 } 1692 if (kopt != NULL) 1693 { 1694 if (alloc_pending (strlen (name) + 80)) 1695 sprintf (pending_error_text, 1696 "E protocol error: both Kopt and Entry for %s", 1697 arg); 1698 free (kopt); 1699 kopt = NULL; 1700 return; 1701 } 1702 found = 1; 1703 break; 1704 } 1705 } 1706 if (!found) 1707 { 1708 /* We got Is-modified but no Entry. Add a dummy entry. 1709 The "D" timestamp is what makes it a dummy. */ 1710 p = (struct an_entry *) malloc (sizeof (struct an_entry)); 1711 if (p == NULL) 1712 { 1713 pending_error = ENOMEM; 1714 return; 1715 } 1716 p->entry = malloc (strlen (arg) + 80); 1717 if (p->entry == NULL) 1718 { 1719 pending_error = ENOMEM; 1720 free (p); 1721 return; 1722 } 1723 strcpy (p->entry, "/"); 1724 strcat (p->entry, arg); 1725 strcat (p->entry, "//D/"); 1726 if (kopt != NULL) 1727 { 1728 strcat (p->entry, kopt); 1729 free (kopt); 1730 kopt = NULL; 1731 } 1732 strcat (p->entry, "/"); 1733 p->next = entries; 1734 entries = p; 1735 } 1736 } 1737 1738 static void serve_entry PROTO ((char *)); 1739 1740 static void 1741 serve_entry (arg) 1742 char *arg; 1743 { 1744 struct an_entry *p; 1745 char *cp; 1746 if (error_pending()) return; 1747 p = (struct an_entry *) malloc (sizeof (struct an_entry)); 1748 if (p == NULL) 1749 { 1750 pending_error = ENOMEM; 1751 return; 1752 } 1753 /* Leave space for serve_unchanged to write '=' if it wants. */ 1754 cp = malloc (strlen (arg) + 2); 1755 if (cp == NULL) 1756 { 1757 pending_error = ENOMEM; 1758 return; 1759 } 1760 strcpy (cp, arg); 1761 p->next = entries; 1762 p->entry = cp; 1763 entries = p; 1764 } 1765 1766 static void serve_kopt PROTO ((char *)); 1767 1768 static void 1769 serve_kopt (arg) 1770 char *arg; 1771 { 1772 if (error_pending ()) 1773 return; 1774 1775 if (kopt != NULL) 1776 { 1777 if (alloc_pending (80 + strlen (arg))) 1778 sprintf (pending_error_text, 1779 "E protocol error: duplicate Kopt request: %s", arg); 1780 return; 1781 } 1782 1783 /* Do some sanity checks. In particular, that it is not too long. 1784 This lets the rest of the code not worry so much about buffer 1785 overrun attacks. Probably should call RCS_check_kflag here, 1786 but that would mean changing RCS_check_kflag to handle errors 1787 other than via exit(), fprintf(), and such. */ 1788 if (strlen (arg) > 10) 1789 { 1790 if (alloc_pending (80 + strlen (arg))) 1791 sprintf (pending_error_text, 1792 "E protocol error: invalid Kopt request: %s", arg); 1793 return; 1794 } 1795 1796 kopt = malloc (strlen (arg) + 1); 1797 if (kopt == NULL) 1798 { 1799 pending_error = ENOMEM; 1800 return; 1801 } 1802 strcpy (kopt, arg); 1803 } 1804 1805 static void serve_checkin_time PROTO ((char *)); 1806 1807 static void 1808 serve_checkin_time (arg) 1809 char *arg; 1810 { 1811 if (error_pending ()) 1812 return; 1813 1814 if (checkin_time_valid) 1815 { 1816 if (alloc_pending (80 + strlen (arg))) 1817 sprintf (pending_error_text, 1818 "E protocol error: duplicate Checkin-time request: %s", 1819 arg); 1820 return; 1821 } 1822 1823 checkin_time = get_date (arg, NULL); 1824 if (checkin_time == (time_t)-1) 1825 { 1826 if (alloc_pending (80 + strlen (arg))) 1827 sprintf (pending_error_text, "E cannot parse date %s", arg); 1828 return; 1829 } 1830 checkin_time_valid = 1; 1831 } 1832 1833 static void 1834 server_write_entries () 1835 { 1836 FILE *f; 1837 struct an_entry *p; 1838 struct an_entry *q; 1839 1840 if (entries == NULL) 1841 return; 1842 1843 f = NULL; 1844 /* Note that we free all the entries regardless of errors. */ 1845 if (!error_pending ()) 1846 { 1847 /* We open in append mode because we don't want to clobber an 1848 existing Entries file. If we are checking out a module 1849 which explicitly lists more than one file in a particular 1850 directory, then we will wind up calling 1851 server_write_entries for each such file. */ 1852 f = CVS_FOPEN (CVSADM_ENT, "a"); 1853 if (f == NULL) 1854 { 1855 pending_error = errno; 1856 if (alloc_pending (80 + strlen (CVSADM_ENT))) 1857 sprintf (pending_error_text, "E cannot open %s", CVSADM_ENT); 1858 } 1859 } 1860 for (p = entries; p != NULL;) 1861 { 1862 if (!error_pending ()) 1863 { 1864 if (fprintf (f, "%s\n", p->entry) < 0) 1865 { 1866 pending_error = errno; 1867 if (alloc_pending (80 + strlen(CVSADM_ENT))) 1868 sprintf (pending_error_text, 1869 "E cannot write to %s", CVSADM_ENT); 1870 } 1871 } 1872 free (p->entry); 1873 q = p->next; 1874 free (p); 1875 p = q; 1876 } 1877 entries = NULL; 1878 if (f != NULL && fclose (f) == EOF && !error_pending ()) 1879 { 1880 pending_error = errno; 1881 if (alloc_pending (80 + strlen (CVSADM_ENT))) 1882 sprintf (pending_error_text, "E cannot close %s", CVSADM_ENT); 1883 } 1884 } 1885 1886 struct notify_note { 1887 /* Directory in which this notification happens. malloc'd*/ 1888 char *dir; 1889 1890 /* malloc'd. */ 1891 char *filename; 1892 1893 /* The following three all in one malloc'd block, pointed to by TYPE. 1894 Each '\0' terminated. */ 1895 /* "E" or "U". */ 1896 char *type; 1897 /* time+host+dir */ 1898 char *val; 1899 char *watches; 1900 1901 struct notify_note *next; 1902 }; 1903 1904 static struct notify_note *notify_list; 1905 /* Used while building list, to point to the last node that already exists. */ 1906 static struct notify_note *last_node; 1907 1908 static void serve_notify PROTO ((char *)); 1909 1910 static void 1911 serve_notify (arg) 1912 char *arg; 1913 { 1914 struct notify_note *new; 1915 char *data; 1916 int status; 1917 1918 if (error_pending ()) return; 1919 1920 if (outside_dir (arg)) 1921 return; 1922 1923 new = (struct notify_note *) malloc (sizeof (struct notify_note)); 1924 if (new == NULL) 1925 { 1926 pending_error = ENOMEM; 1927 return; 1928 } 1929 if (dir_name == NULL) 1930 goto error; 1931 new->dir = malloc (strlen (dir_name) + 1); 1932 if (new->dir == NULL) 1933 { 1934 pending_error = ENOMEM; 1935 return; 1936 } 1937 strcpy (new->dir, dir_name); 1938 new->filename = malloc (strlen (arg) + 1); 1939 if (new->filename == NULL) 1940 { 1941 pending_error = ENOMEM; 1942 return; 1943 } 1944 strcpy (new->filename, arg); 1945 1946 status = buf_read_line (buf_from_net, &data, (int *) NULL); 1947 if (status != 0) 1948 { 1949 if (status == -2) 1950 pending_error = ENOMEM; 1951 else 1952 { 1953 pending_error_text = malloc (80 + strlen (arg)); 1954 if (pending_error_text == NULL) 1955 pending_error = ENOMEM; 1956 else 1957 { 1958 if (status == -1) 1959 sprintf (pending_error_text, 1960 "E end of file reading notification for %s", arg); 1961 else 1962 { 1963 sprintf (pending_error_text, 1964 "E error reading notification for %s", arg); 1965 pending_error = status; 1966 } 1967 } 1968 } 1969 } 1970 else 1971 { 1972 char *cp; 1973 1974 if (strchr (data, '+')) 1975 goto error; 1976 1977 new->type = data; 1978 if (data[1] != '\t') 1979 goto error; 1980 data[1] = '\0'; 1981 cp = data + 2; 1982 new->val = cp; 1983 cp = strchr (cp, '\t'); 1984 if (cp == NULL) 1985 goto error; 1986 *cp++ = '+'; 1987 cp = strchr (cp, '\t'); 1988 if (cp == NULL) 1989 goto error; 1990 *cp++ = '+'; 1991 cp = strchr (cp, '\t'); 1992 if (cp == NULL) 1993 goto error; 1994 *cp++ = '\0'; 1995 new->watches = cp; 1996 /* If there is another tab, ignore everything after it, 1997 for future expansion. */ 1998 cp = strchr (cp, '\t'); 1999 if (cp != NULL) 2000 { 2001 *cp = '\0'; 2002 } 2003 2004 new->next = NULL; 2005 2006 if (last_node == NULL) 2007 { 2008 notify_list = new; 2009 } 2010 else 2011 last_node->next = new; 2012 last_node = new; 2013 } 2014 return; 2015 error: 2016 pending_error_text = malloc (80); 2017 if (pending_error_text) 2018 strcpy (pending_error_text, 2019 "E Protocol error; misformed Notify request"); 2020 pending_error = 0; 2021 return; 2022 } 2023 2024 /* Process all the Notify requests that we have stored up. Returns 0 2025 if successful, if not prints error message (via error()) and 2026 returns negative value. */ 2027 static int 2028 server_notify () 2029 { 2030 struct notify_note *p; 2031 char *repos; 2032 2033 while (notify_list != NULL) 2034 { 2035 if ( CVS_CHDIR (notify_list->dir) < 0) 2036 { 2037 error (0, errno, "cannot change to %s", notify_list->dir); 2038 return -1; 2039 } 2040 repos = Name_Repository (NULL, NULL); 2041 2042 lock_dir_for_write (repos); 2043 2044 fileattr_startdir (repos); 2045 2046 notify_do (*notify_list->type, notify_list->filename, getcaller(), 2047 notify_list->val, notify_list->watches, repos); 2048 2049 buf_output0 (buf_to_net, "Notified "); 2050 { 2051 char *dir = notify_list->dir + strlen (server_temp_dir) + 1; 2052 if (dir[0] == '\0') 2053 buf_append_char (buf_to_net, '.'); 2054 else 2055 buf_output0 (buf_to_net, dir); 2056 buf_append_char (buf_to_net, '/'); 2057 buf_append_char (buf_to_net, '\n'); 2058 } 2059 buf_output0 (buf_to_net, repos); 2060 buf_append_char (buf_to_net, '/'); 2061 buf_output0 (buf_to_net, notify_list->filename); 2062 buf_append_char (buf_to_net, '\n'); 2063 2064 p = notify_list->next; 2065 free (notify_list->filename); 2066 free (notify_list->dir); 2067 free (notify_list->type); 2068 free (notify_list); 2069 notify_list = p; 2070 2071 fileattr_write (); 2072 fileattr_free (); 2073 2074 Lock_Cleanup (); 2075 } 2076 2077 last_node = NULL; 2078 2079 /* The code used to call fflush (stdout) here, but that is no 2080 longer necessary. The data is now buffered in buf_to_net, 2081 which will be flushed by the caller, do_cvs_command. */ 2082 2083 return 0; 2084 } 2085 2086 static int argument_count; 2087 static char **argument_vector; 2088 static int argument_vector_size; 2089 2090 static void 2091 serve_argument (arg) 2092 char *arg; 2093 { 2094 char *p; 2095 2096 if (error_pending()) return; 2097 2098 if (argument_vector_size <= argument_count) 2099 { 2100 argument_vector_size *= 2; 2101 argument_vector = 2102 (char **) realloc ((char *)argument_vector, 2103 argument_vector_size * sizeof (char *)); 2104 if (argument_vector == NULL) 2105 { 2106 pending_error = ENOMEM; 2107 return; 2108 } 2109 } 2110 p = malloc (strlen (arg) + 1); 2111 if (p == NULL) 2112 { 2113 pending_error = ENOMEM; 2114 return; 2115 } 2116 strcpy (p, arg); 2117 argument_vector[argument_count++] = p; 2118 } 2119 2120 static void 2121 serve_argumentx (arg) 2122 char *arg; 2123 { 2124 char *p; 2125 2126 if (error_pending()) return; 2127 2128 p = argument_vector[argument_count - 1]; 2129 p = realloc (p, strlen (p) + 1 + strlen (arg) + 1); 2130 if (p == NULL) 2131 { 2132 pending_error = ENOMEM; 2133 return; 2134 } 2135 strcat (p, "\n"); 2136 strcat (p, arg); 2137 argument_vector[argument_count - 1] = p; 2138 } 2139 2140 static void 2141 serve_global_option (arg) 2142 char *arg; 2143 { 2144 if (arg[0] != '-' || arg[1] == '\0' || arg[2] != '\0') 2145 { 2146 error_return: 2147 if (alloc_pending (strlen (arg) + 80)) 2148 sprintf (pending_error_text, 2149 "E Protocol error: bad global option %s", 2150 arg); 2151 return; 2152 } 2153 switch (arg[1]) 2154 { 2155 case 'n': 2156 noexec = 1; 2157 break; 2158 case 'q': 2159 quiet = 1; 2160 break; 2161 case 'r': 2162 cvswrite = 0; 2163 break; 2164 case 'Q': 2165 really_quiet = 1; 2166 break; 2167 case 'l': 2168 logoff = 1; 2169 break; 2170 case 't': 2171 trace = 1; 2172 break; 2173 default: 2174 goto error_return; 2175 } 2176 } 2177 2178 static void 2179 serve_set (arg) 2180 char *arg; 2181 { 2182 /* FIXME: This sends errors immediately (I think); they should be 2183 put into pending_error. */ 2184 variable_set (arg); 2185 } 2186 2187 #ifdef ENCRYPTION 2188 2189 #ifdef HAVE_KERBEROS 2190 2191 static void 2192 serve_kerberos_encrypt (arg) 2193 char *arg; 2194 { 2195 /* All future communication with the client will be encrypted. */ 2196 2197 buf_to_net = krb_encrypt_buffer_initialize (buf_to_net, 0, sched, 2198 kblock, 2199 buf_to_net->memory_error); 2200 buf_from_net = krb_encrypt_buffer_initialize (buf_from_net, 1, sched, 2201 kblock, 2202 buf_from_net->memory_error); 2203 } 2204 2205 #endif /* HAVE_KERBEROS */ 2206 2207 #ifdef HAVE_GSSAPI 2208 2209 static void 2210 serve_gssapi_encrypt (arg) 2211 char *arg; 2212 { 2213 if (cvs_gssapi_wrapping) 2214 { 2215 /* We're already using a gssapi_wrap buffer for stream 2216 authentication. Flush everything we've output so far, and 2217 turn on encryption for future data. On the input side, we 2218 should only have unwrapped as far as the Gssapi-encrypt 2219 command, so future unwrapping will become encrypted. */ 2220 buf_flush (buf_to_net, 1); 2221 cvs_gssapi_encrypt = 1; 2222 return; 2223 } 2224 2225 /* All future communication with the client will be encrypted. */ 2226 2227 cvs_gssapi_encrypt = 1; 2228 2229 buf_to_net = cvs_gssapi_wrap_buffer_initialize (buf_to_net, 0, 2230 gcontext, 2231 buf_to_net->memory_error); 2232 buf_from_net = cvs_gssapi_wrap_buffer_initialize (buf_from_net, 1, 2233 gcontext, 2234 buf_from_net->memory_error); 2235 2236 cvs_gssapi_wrapping = 1; 2237 } 2238 2239 #endif /* HAVE_GSSAPI */ 2240 2241 #endif /* ENCRYPTION */ 2242 2243 #ifdef HAVE_GSSAPI 2244 2245 static void 2246 serve_gssapi_authenticate (arg) 2247 char *arg; 2248 { 2249 if (cvs_gssapi_wrapping) 2250 { 2251 /* We're already using a gssapi_wrap buffer for encryption. 2252 That includes authentication, so we don't have to do 2253 anything further. */ 2254 return; 2255 } 2256 2257 buf_to_net = cvs_gssapi_wrap_buffer_initialize (buf_to_net, 0, 2258 gcontext, 2259 buf_to_net->memory_error); 2260 buf_from_net = cvs_gssapi_wrap_buffer_initialize (buf_from_net, 1, 2261 gcontext, 2262 buf_from_net->memory_error); 2263 2264 cvs_gssapi_wrapping = 1; 2265 } 2266 2267 #endif /* HAVE_GSSAPI */ 2268 2269 #ifdef SERVER_FLOWCONTROL 2270 /* The maximum we'll queue to the remote client before blocking. */ 2271 # ifndef SERVER_HI_WATER 2272 # define SERVER_HI_WATER (2 * 1024 * 1024) 2273 # endif /* SERVER_HI_WATER */ 2274 /* When the buffer drops to this, we restart the child */ 2275 # ifndef SERVER_LO_WATER 2276 # define SERVER_LO_WATER (1 * 1024 * 1024) 2277 # endif /* SERVER_LO_WATER */ 2278 2279 static int set_nonblock_fd PROTO((int)); 2280 2281 /* 2282 * Set buffer BUF to non-blocking I/O. Returns 0 for success or errno 2283 * code. 2284 */ 2285 2286 static int 2287 set_nonblock_fd (fd) 2288 int fd; 2289 { 2290 int flags; 2291 2292 flags = fcntl (fd, F_GETFL, 0); 2293 if (flags < 0) 2294 return errno; 2295 if (fcntl (fd, F_SETFL, flags | O_NONBLOCK) < 0) 2296 return errno; 2297 return 0; 2298 } 2299 2300 #endif /* SERVER_FLOWCONTROL */ 2301 2302 static void serve_questionable PROTO((char *)); 2303 2304 static void 2305 serve_questionable (arg) 2306 char *arg; 2307 { 2308 static int initted; 2309 2310 if (!initted) 2311 { 2312 /* Pick up ignores from CVSROOTADM_IGNORE, $HOME/.cvsignore on server, 2313 and CVSIGNORE on server. */ 2314 ign_setup (); 2315 initted = 1; 2316 } 2317 2318 if (dir_name == NULL) 2319 { 2320 buf_output0 (buf_to_net, "E Protocol error: 'Directory' missing"); 2321 return; 2322 } 2323 2324 if (outside_dir (arg)) 2325 return; 2326 2327 if (!ign_name (arg)) 2328 { 2329 char *update_dir; 2330 2331 buf_output (buf_to_net, "M ? ", 4); 2332 update_dir = dir_name + strlen (server_temp_dir) + 1; 2333 if (!(update_dir[0] == '.' && update_dir[1] == '\0')) 2334 { 2335 buf_output0 (buf_to_net, update_dir); 2336 buf_output (buf_to_net, "/", 1); 2337 } 2338 buf_output0 (buf_to_net, arg); 2339 buf_output (buf_to_net, "\n", 1); 2340 } 2341 } 2342 2343 static void serve_case PROTO ((char *)); 2344 2345 static void 2346 serve_case (arg) 2347 char *arg; 2348 { 2349 ign_case = 1; 2350 } 2351 2352 static struct buffer *protocol; 2353 2354 /* This is the output which we are saving up to send to the server, in the 2355 child process. We will push it through, via the `protocol' buffer, when 2356 we have a complete line. */ 2357 static struct buffer *saved_output; 2358 /* Likewise, but stuff which will go to stderr. */ 2359 static struct buffer *saved_outerr; 2360 2361 static void 2362 protocol_memory_error (buf) 2363 struct buffer *buf; 2364 { 2365 error (1, ENOMEM, "Virtual memory exhausted"); 2366 } 2367 2368 /* 2369 * Process IDs of the subprocess, or negative if that subprocess 2370 * does not exist. 2371 */ 2372 static pid_t command_pid; 2373 2374 static void 2375 outbuf_memory_error (buf) 2376 struct buffer *buf; 2377 { 2378 static const char msg[] = "E Fatal server error\n\ 2379 error ENOMEM Virtual memory exhausted.\n"; 2380 if (command_pid > 0) 2381 kill (command_pid, SIGTERM); 2382 2383 /* 2384 * We have arranged things so that printing this now either will 2385 * be legal, or the "E fatal error" line will get glommed onto the 2386 * end of an existing "E" or "M" response. 2387 */ 2388 2389 /* If this gives an error, not much we could do. syslog() it? */ 2390 write (STDOUT_FILENO, msg, sizeof (msg) - 1); 2391 error_exit (); 2392 } 2393 2394 static void 2395 input_memory_error (buf) 2396 struct buffer *buf; 2397 { 2398 outbuf_memory_error (buf); 2399 } 2400 2401 2402 2403 /* If command is legal, return 1. 2404 * Else if command is illegal and croak_on_illegal is set, then die. 2405 * Else just return 0 to indicate that command is illegal. 2406 */ 2407 static int 2408 check_command_legal_p (cmd_name) 2409 char *cmd_name; 2410 { 2411 /* Right now, only pserver notices illegal commands -- namely, 2412 * write attempts by a read-only user. Therefore, if CVS_Username 2413 * is not set, this just returns 1, because CVS_Username unset 2414 * means pserver is not active. 2415 */ 2416 #ifdef AUTH_SERVER_SUPPORT 2417 if (CVS_Username == NULL) 2418 return 1; 2419 2420 if (lookup_command_attribute (cmd_name) & CVS_CMD_MODIFIES_REPOSITORY) 2421 { 2422 /* This command has the potential to modify the repository, so 2423 * we check if the user have permission to do that. 2424 * 2425 * (Only relevant for remote users -- local users can do 2426 * whatever normal Unix file permissions allow them to do.) 2427 * 2428 * The decision method: 2429 * 2430 * If $CVSROOT/CVSADMROOT_READERS exists and user is listed 2431 * in it, then read-only access for user. 2432 * 2433 * Or if $CVSROOT/CVSADMROOT_WRITERS exists and user NOT 2434 * listed in it, then also read-only access for user. 2435 * 2436 * Else read-write access for user. 2437 */ 2438 2439 char *linebuf = NULL; 2440 int num_red = 0; 2441 size_t linebuf_len = 0; 2442 char *fname; 2443 size_t flen; 2444 FILE *fp; 2445 int found_it = 0; 2446 2447 /* else */ 2448 flen = strlen (CVSroot_directory) 2449 + strlen (CVSROOTADM) 2450 + strlen (CVSROOTADM_READERS) 2451 + 3; 2452 2453 fname = xmalloc (flen); 2454 (void) sprintf (fname, "%s/%s/%s", CVSroot_directory, 2455 CVSROOTADM, CVSROOTADM_READERS); 2456 2457 fp = fopen (fname, "r"); 2458 2459 if (fp == NULL) 2460 { 2461 if (!existence_error (errno)) 2462 { 2463 /* Need to deny access, so that attackers can't fool 2464 us with some sort of denial of service attack. */ 2465 error (0, errno, "cannot open %s", fname); 2466 free (fname); 2467 return 0; 2468 } 2469 } 2470 else /* successfully opened readers file */ 2471 { 2472 while ((num_red = getline (&linebuf, &linebuf_len, fp)) >= 0) 2473 { 2474 /* Hmmm, is it worth importing my own readline 2475 library into CVS? It takes care of chopping 2476 leading and trailing whitespace, "#" comments, and 2477 newlines automatically when so requested. Would 2478 save some code here... -kff */ 2479 2480 /* Chop newline by hand, for strcmp()'s sake. */ 2481 if (linebuf[num_red - 1] == '\n') 2482 linebuf[num_red - 1] = '\0'; 2483 2484 if (strcmp (linebuf, CVS_Username) == 0) 2485 goto handle_illegal; 2486 } 2487 if (num_red < 0 && !feof (fp)) 2488 error (0, errno, "cannot read %s", fname); 2489 2490 /* If not listed specifically as a reader, then this user 2491 has write access by default unless writers are also 2492 specified in a file . */ 2493 if (fclose (fp) < 0) 2494 error (0, errno, "cannot close %s", fname); 2495 } 2496 free (fname); 2497 2498 /* Now check the writers file. */ 2499 2500 flen = strlen (CVSroot_directory) 2501 + strlen (CVSROOTADM) 2502 + strlen (CVSROOTADM_WRITERS) 2503 + 3; 2504 2505 fname = xmalloc (flen); 2506 (void) sprintf (fname, "%s/%s/%s", CVSroot_directory, 2507 CVSROOTADM, CVSROOTADM_WRITERS); 2508 2509 fp = fopen (fname, "r"); 2510 2511 if (fp == NULL) 2512 { 2513 if (linebuf) 2514 free (linebuf); 2515 if (existence_error (errno)) 2516 { 2517 /* Writers file does not exist, so everyone is a writer, 2518 by default. */ 2519 free (fname); 2520 return 1; 2521 } 2522 else 2523 { 2524 /* Need to deny access, so that attackers can't fool 2525 us with some sort of denial of service attack. */ 2526 error (0, errno, "cannot read %s", fname); 2527 free (fname); 2528 return 0; 2529 } 2530 } 2531 2532 found_it = 0; 2533 while ((num_red = getline (&linebuf, &linebuf_len, fp)) >= 0) 2534 { 2535 /* Chop newline by hand, for strcmp()'s sake. */ 2536 if (linebuf[num_red - 1] == '\n') 2537 linebuf[num_red - 1] = '\0'; 2538 2539 if (strcmp (linebuf, CVS_Username) == 0) 2540 { 2541 found_it = 1; 2542 break; 2543 } 2544 } 2545 if (num_red < 0 && !feof (fp)) 2546 error (0, errno, "cannot read %s", fname); 2547 2548 if (found_it) 2549 { 2550 if (fclose (fp) < 0) 2551 error (0, errno, "cannot close %s", fname); 2552 if (linebuf) 2553 free (linebuf); 2554 free (fname); 2555 return 1; 2556 } 2557 else /* writers file exists, but this user not listed in it */ 2558 { 2559 handle_illegal: 2560 if (fclose (fp) < 0) 2561 error (0, errno, "cannot close %s", fname); 2562 if (linebuf) 2563 free (linebuf); 2564 free (fname); 2565 return 0; 2566 } 2567 } 2568 #endif /* AUTH_SERVER_SUPPORT */ 2569 2570 /* If ever reach end of this function, command must be legal. */ 2571 return 1; 2572 } 2573 2574 2575 2576 /* Execute COMMAND in a subprocess with the approriate funky things done. */ 2577 2578 static struct fd_set_wrapper { fd_set fds; } command_fds_to_drain; 2579 static int max_command_fd; 2580 2581 #ifdef SERVER_FLOWCONTROL 2582 static int flowcontrol_pipe[2]; 2583 #endif /* SERVER_FLOWCONTROL */ 2584 2585 static void 2586 do_cvs_command (cmd_name, command) 2587 char *cmd_name; 2588 int (*command) PROTO((int argc, char **argv)); 2589 { 2590 /* 2591 * The following file descriptors are set to -1 if that file is not 2592 * currently open. 2593 */ 2594 2595 /* Data on these pipes is a series of '\n'-terminated lines. */ 2596 int stdout_pipe[2]; 2597 int stderr_pipe[2]; 2598 2599 /* 2600 * Data on this pipe is a series of counted (see buf_send_counted) 2601 * packets. Each packet must be processed atomically (i.e. not 2602 * interleaved with data from stdout_pipe or stderr_pipe). 2603 */ 2604 int protocol_pipe[2]; 2605 2606 int dev_null_fd = -1; 2607 2608 int errs; 2609 2610 command_pid = -1; 2611 stdout_pipe[0] = -1; 2612 stdout_pipe[1] = -1; 2613 stderr_pipe[0] = -1; 2614 stderr_pipe[1] = -1; 2615 protocol_pipe[0] = -1; 2616 protocol_pipe[1] = -1; 2617 2618 server_write_entries (); 2619 2620 if (print_pending_error ()) 2621 goto free_args_and_return; 2622 2623 /* Global `command_name' is probably "server" right now -- only 2624 serve_export() sets it to anything else. So we will use local 2625 parameter `cmd_name' to determine if this command is legal for 2626 this user. */ 2627 if (!check_command_legal_p (cmd_name)) 2628 { 2629 buf_output0 (buf_to_net, "E "); 2630 buf_output0 (buf_to_net, program_name); 2631 buf_output0 (buf_to_net, " [server aborted]: \""); 2632 buf_output0 (buf_to_net, cmd_name); 2633 buf_output0 (buf_to_net, "\" requires write access to the repository\n\ 2634 error \n"); 2635 goto free_args_and_return; 2636 } 2637 2638 (void) server_notify (); 2639 2640 /* 2641 * We use a child process which actually does the operation. This 2642 * is so we can intercept its standard output. Even if all of CVS 2643 * were written to go to some special routine instead of writing 2644 * to stdout or stderr, we would still need to do the same thing 2645 * for the RCS commands. 2646 */ 2647 2648 if (pipe (stdout_pipe) < 0) 2649 { 2650 print_error (errno); 2651 goto error_exit; 2652 } 2653 if (pipe (stderr_pipe) < 0) 2654 { 2655 print_error (errno); 2656 goto error_exit; 2657 } 2658 if (pipe (protocol_pipe) < 0) 2659 { 2660 print_error (errno); 2661 goto error_exit; 2662 } 2663 #ifdef SERVER_FLOWCONTROL 2664 if (pipe (flowcontrol_pipe) < 0) 2665 { 2666 print_error (errno); 2667 goto error_exit; 2668 } 2669 set_nonblock_fd (flowcontrol_pipe[0]); 2670 set_nonblock_fd (flowcontrol_pipe[1]); 2671 #endif /* SERVER_FLOWCONTROL */ 2672 2673 dev_null_fd = CVS_OPEN (DEVNULL, O_RDONLY); 2674 if (dev_null_fd < 0) 2675 { 2676 print_error (errno); 2677 goto error_exit; 2678 } 2679 2680 /* We shouldn't have any partial lines from cvs_output and 2681 cvs_outerr, but we handle them here in case there is a bug. */ 2682 /* FIXME: appending a newline, rather than using "MT" as we 2683 do in the child process, is probably not really a very good 2684 way to "handle" them. */ 2685 if (! buf_empty_p (saved_output)) 2686 { 2687 buf_append_char (saved_output, '\n'); 2688 buf_copy_lines (buf_to_net, saved_output, 'M'); 2689 } 2690 if (! buf_empty_p (saved_outerr)) 2691 { 2692 buf_append_char (saved_outerr, '\n'); 2693 buf_copy_lines (buf_to_net, saved_outerr, 'E'); 2694 } 2695 2696 /* Flush out any pending data. */ 2697 buf_flush (buf_to_net, 1); 2698 2699 /* Don't use vfork; we're not going to exec(). */ 2700 command_pid = fork (); 2701 if (command_pid < 0) 2702 { 2703 print_error (errno); 2704 goto error_exit; 2705 } 2706 if (command_pid == 0) 2707 { 2708 int exitstatus; 2709 2710 /* Since we're in the child, and the parent is going to take 2711 care of packaging up our error messages, we can clear this 2712 flag. */ 2713 error_use_protocol = 0; 2714 2715 protocol = fd_buffer_initialize (protocol_pipe[1], 0, 2716 protocol_memory_error); 2717 2718 /* At this point we should no longer be using buf_to_net and 2719 buf_from_net. Instead, everything should go through 2720 protocol. */ 2721 buf_to_net = NULL; 2722 buf_from_net = NULL; 2723 2724 /* These were originally set up to use outbuf_memory_error. 2725 Since we're now in the child, we should use the simpler 2726 protocol_memory_error function. */ 2727 saved_output->memory_error = protocol_memory_error; 2728 saved_outerr->memory_error = protocol_memory_error; 2729 2730 if (dup2 (dev_null_fd, STDIN_FILENO) < 0) 2731 error (1, errno, "can't set up pipes"); 2732 if (dup2 (stdout_pipe[1], STDOUT_FILENO) < 0) 2733 error (1, errno, "can't set up pipes"); 2734 if (dup2 (stderr_pipe[1], STDERR_FILENO) < 0) 2735 error (1, errno, "can't set up pipes"); 2736 close (stdout_pipe[0]); 2737 close (stderr_pipe[0]); 2738 close (protocol_pipe[0]); 2739 #ifdef SERVER_FLOWCONTROL 2740 close (flowcontrol_pipe[1]); 2741 #endif /* SERVER_FLOWCONTROL */ 2742 2743 /* 2744 * Set this in .bashrc if you want to give yourself time to attach 2745 * to the subprocess with a debugger. 2746 */ 2747 if (getenv ("CVS_SERVER_SLEEP")) 2748 { 2749 int secs = atoi (getenv ("CVS_SERVER_SLEEP")); 2750 sleep (secs); 2751 } 2752 2753 exitstatus = (*command) (argument_count, argument_vector); 2754 2755 /* Output any partial lines. If the client doesn't support 2756 "MT", we just throw out the partial line, like old versions 2757 of CVS did, since the protocol can't support this. */ 2758 if (supported_response ("MT") && ! buf_empty_p (saved_output)) 2759 { 2760 buf_output0 (protocol, "MT text "); 2761 buf_append_buffer (protocol, saved_output); 2762 buf_output (protocol, "\n", 1); 2763 buf_send_counted (protocol); 2764 } 2765 /* For now we just discard partial lines on stderr. I suspect 2766 that CVS can't write such lines unless there is a bug. */ 2767 2768 /* 2769 * When we exit, that will close the pipes, giving an EOF to 2770 * the parent. 2771 */ 2772 exit (exitstatus); 2773 } 2774 2775 /* OK, sit around getting all the input from the child. */ 2776 { 2777 struct buffer *stdoutbuf; 2778 struct buffer *stderrbuf; 2779 struct buffer *protocol_inbuf; 2780 /* Number of file descriptors to check in select (). */ 2781 int num_to_check; 2782 int count_needed = 0; 2783 #ifdef SERVER_FLOWCONTROL 2784 int have_flowcontrolled = 0; 2785 #endif /* SERVER_FLOWCONTROL */ 2786 2787 FD_ZERO (&command_fds_to_drain.fds); 2788 num_to_check = stdout_pipe[0]; 2789 FD_SET (stdout_pipe[0], &command_fds_to_drain.fds); 2790 if (stderr_pipe[0] > num_to_check) 2791 num_to_check = stderr_pipe[0]; 2792 FD_SET (stderr_pipe[0], &command_fds_to_drain.fds); 2793 if (protocol_pipe[0] > num_to_check) 2794 num_to_check = protocol_pipe[0]; 2795 FD_SET (protocol_pipe[0], &command_fds_to_drain.fds); 2796 if (STDOUT_FILENO > num_to_check) 2797 num_to_check = STDOUT_FILENO; 2798 max_command_fd = num_to_check; 2799 /* 2800 * File descriptors are numbered from 0, so num_to_check needs to 2801 * be one larger than the largest descriptor. 2802 */ 2803 ++num_to_check; 2804 if (num_to_check > FD_SETSIZE) 2805 { 2806 buf_output0 (buf_to_net, 2807 "E internal error: FD_SETSIZE not big enough.\n\ 2808 error \n"); 2809 goto error_exit; 2810 } 2811 2812 stdoutbuf = fd_buffer_initialize (stdout_pipe[0], 1, 2813 input_memory_error); 2814 2815 stderrbuf = fd_buffer_initialize (stderr_pipe[0], 1, 2816 input_memory_error); 2817 2818 protocol_inbuf = fd_buffer_initialize (protocol_pipe[0], 1, 2819 input_memory_error); 2820 2821 set_nonblock (buf_to_net); 2822 set_nonblock (stdoutbuf); 2823 set_nonblock (stderrbuf); 2824 set_nonblock (protocol_inbuf); 2825 2826 if (close (stdout_pipe[1]) < 0) 2827 { 2828 print_error (errno); 2829 goto error_exit; 2830 } 2831 stdout_pipe[1] = -1; 2832 2833 if (close (stderr_pipe[1]) < 0) 2834 { 2835 print_error (errno); 2836 goto error_exit; 2837 } 2838 stderr_pipe[1] = -1; 2839 2840 if (close (protocol_pipe[1]) < 0) 2841 { 2842 print_error (errno); 2843 goto error_exit; 2844 } 2845 protocol_pipe[1] = -1; 2846 2847 #ifdef SERVER_FLOWCONTROL 2848 if (close (flowcontrol_pipe[0]) < 0) 2849 { 2850 print_error (errno); 2851 goto error_exit; 2852 } 2853 flowcontrol_pipe[0] = -1; 2854 #endif /* SERVER_FLOWCONTROL */ 2855 2856 if (close (dev_null_fd) < 0) 2857 { 2858 print_error (errno); 2859 goto error_exit; 2860 } 2861 dev_null_fd = -1; 2862 2863 while (stdout_pipe[0] >= 0 2864 || stderr_pipe[0] >= 0 2865 || protocol_pipe[0] >= 0) 2866 { 2867 fd_set readfds; 2868 fd_set writefds; 2869 int numfds; 2870 #ifdef SERVER_FLOWCONTROL 2871 int bufmemsize; 2872 2873 /* 2874 * See if we are swamping the remote client and filling our VM. 2875 * Tell child to hold off if we do. 2876 */ 2877 bufmemsize = buf_count_mem (buf_to_net); 2878 if (!have_flowcontrolled && (bufmemsize > SERVER_HI_WATER)) 2879 { 2880 if (write(flowcontrol_pipe[1], "S", 1) == 1) 2881 have_flowcontrolled = 1; 2882 } 2883 else if (have_flowcontrolled && (bufmemsize < SERVER_LO_WATER)) 2884 { 2885 if (write(flowcontrol_pipe[1], "G", 1) == 1) 2886 have_flowcontrolled = 0; 2887 } 2888 #endif /* SERVER_FLOWCONTROL */ 2889 2890 FD_ZERO (&readfds); 2891 FD_ZERO (&writefds); 2892 if (! buf_empty_p (buf_to_net)) 2893 FD_SET (STDOUT_FILENO, &writefds); 2894 2895 if (stdout_pipe[0] >= 0) 2896 { 2897 FD_SET (stdout_pipe[0], &readfds); 2898 } 2899 if (stderr_pipe[0] >= 0) 2900 { 2901 FD_SET (stderr_pipe[0], &readfds); 2902 } 2903 if (protocol_pipe[0] >= 0) 2904 { 2905 FD_SET (protocol_pipe[0], &readfds); 2906 } 2907 2908 /* This process of selecting on the three pipes means that 2909 we might not get output in the same order in which it 2910 was written, thus producing the well-known 2911 "out-of-order" bug. If the child process uses 2912 cvs_output and cvs_outerr, it will send everything on 2913 the protocol_pipe and avoid this problem, so the 2914 solution is to use cvs_output and cvs_outerr in the 2915 child process. */ 2916 do { 2917 /* This used to select on exceptions too, but as far 2918 as I know there was never any reason to do that and 2919 SCO doesn't let you select on exceptions on pipes. */ 2920 numfds = select (num_to_check, &readfds, &writefds, 2921 (fd_set *)0, (struct timeval *)NULL); 2922 if (numfds < 0 2923 && errno != EINTR) 2924 { 2925 print_error (errno); 2926 goto error_exit; 2927 } 2928 } while (numfds < 0); 2929 2930 if (FD_ISSET (STDOUT_FILENO, &writefds)) 2931 { 2932 /* What should we do with errors? syslog() them? */ 2933 buf_send_output (buf_to_net); 2934 } 2935 2936 if (stdout_pipe[0] >= 0 2937 && (FD_ISSET (stdout_pipe[0], &readfds))) 2938 { 2939 int status; 2940 2941 status = buf_input_data (stdoutbuf, (int *) NULL); 2942 2943 buf_copy_lines (buf_to_net, stdoutbuf, 'M'); 2944 2945 if (status == -1) 2946 stdout_pipe[0] = -1; 2947 else if (status > 0) 2948 { 2949 print_error (status); 2950 goto error_exit; 2951 } 2952 2953 /* What should we do with errors? syslog() them? */ 2954 buf_send_output (buf_to_net); 2955 } 2956 2957 if (stderr_pipe[0] >= 0 2958 && (FD_ISSET (stderr_pipe[0], &readfds))) 2959 { 2960 int status; 2961 2962 status = buf_input_data (stderrbuf, (int *) NULL); 2963 2964 buf_copy_lines (buf_to_net, stderrbuf, 'E'); 2965 2966 if (status == -1) 2967 stderr_pipe[0] = -1; 2968 else if (status > 0) 2969 { 2970 print_error (status); 2971 goto error_exit; 2972 } 2973 2974 /* What should we do with errors? syslog() them? */ 2975 buf_send_output (buf_to_net); 2976 } 2977 2978 if (protocol_pipe[0] >= 0 2979 && (FD_ISSET (protocol_pipe[0], &readfds))) 2980 { 2981 int status; 2982 int count_read; 2983 int special; 2984 2985 status = buf_input_data (protocol_inbuf, &count_read); 2986 2987 if (status == -1) 2988 protocol_pipe[0] = -1; 2989 else if (status > 0) 2990 { 2991 print_error (status); 2992 goto error_exit; 2993 } 2994 2995 /* 2996 * We only call buf_copy_counted if we have read 2997 * enough bytes to make it worthwhile. This saves us 2998 * from continually recounting the amount of data we 2999 * have. 3000 */ 3001 count_needed -= count_read; 3002 while (count_needed <= 0) 3003 { 3004 count_needed = buf_copy_counted (buf_to_net, 3005 protocol_inbuf, 3006 &special); 3007 3008 /* What should we do with errors? syslog() them? */ 3009 buf_send_output (buf_to_net); 3010 3011 /* If SPECIAL got set to -1, it means that the child 3012 wants us to flush the pipe. We don't want to block 3013 on the network, but we flush what we can. If the 3014 client supports the 'F' command, we send it. */ 3015 if (special == -1) 3016 { 3017 if (supported_response ("F")) 3018 { 3019 buf_append_char (buf_to_net, 'F'); 3020 buf_append_char (buf_to_net, '\n'); 3021 } 3022 3023 cvs_flusherr (); 3024 } 3025 } 3026 } 3027 } 3028 3029 /* 3030 * OK, we've gotten EOF on all the pipes. If there is 3031 * anything left on stdoutbuf or stderrbuf (this could only 3032 * happen if there was no trailing newline), send it over. 3033 */ 3034 if (! buf_empty_p (stdoutbuf)) 3035 { 3036 buf_append_char (stdoutbuf, '\n'); 3037 buf_copy_lines (buf_to_net, stdoutbuf, 'M'); 3038 } 3039 if (! buf_empty_p (stderrbuf)) 3040 { 3041 buf_append_char (stderrbuf, '\n'); 3042 buf_copy_lines (buf_to_net, stderrbuf, 'E'); 3043 } 3044 if (! buf_empty_p (protocol_inbuf)) 3045 buf_output0 (buf_to_net, 3046 "E Protocol error: uncounted data discarded\n"); 3047 3048 errs = 0; 3049 3050 while (command_pid > 0) 3051 { 3052 int status; 3053 pid_t waited_pid; 3054 waited_pid = waitpid (command_pid, &status, 0); 3055 if (waited_pid < 0) 3056 { 3057 /* 3058 * Intentionally ignoring EINTR. Other errors 3059 * "can't happen". 3060 */ 3061 continue; 3062 } 3063 3064 if (WIFEXITED (status)) 3065 errs += WEXITSTATUS (status); 3066 else 3067 { 3068 int sig = WTERMSIG (status); 3069 char buf[50]; 3070 /* 3071 * This is really evil, because signals might be numbered 3072 * differently on the two systems. We should be using 3073 * signal names (either of the "Terminated" or the "SIGTERM" 3074 * variety). But cvs doesn't currently use libiberty...we 3075 * could roll our own.... FIXME. 3076 */ 3077 buf_output0 (buf_to_net, "E Terminated with fatal signal "); 3078 sprintf (buf, "%d\n", sig); 3079 buf_output0 (buf_to_net, buf); 3080 3081 /* Test for a core dump. Is this portable? */ 3082 if (status & 0x80) 3083 { 3084 buf_output0 (buf_to_net, "E Core dumped; preserving "); 3085 buf_output0 (buf_to_net, orig_server_temp_dir); 3086 buf_output0 (buf_to_net, " on server.\n\ 3087 E CVS locks may need cleaning up.\n"); 3088 dont_delete_temp = 1; 3089 } 3090 ++errs; 3091 } 3092 if (waited_pid == command_pid) 3093 command_pid = -1; 3094 } 3095 3096 /* 3097 * OK, we've waited for the child. By now all CVS locks are free 3098 * and it's OK to block on the network. 3099 */ 3100 set_block (buf_to_net); 3101 buf_flush (buf_to_net, 1); 3102 } 3103 3104 if (errs) 3105 /* We will have printed an error message already. */ 3106 buf_output0 (buf_to_net, "error \n"); 3107 else 3108 buf_output0 (buf_to_net, "ok\n"); 3109 goto free_args_and_return; 3110 3111 error_exit: 3112 if (command_pid > 0) 3113 kill (command_pid, SIGTERM); 3114 3115 while (command_pid > 0) 3116 { 3117 pid_t waited_pid; 3118 waited_pid = waitpid (command_pid, (int *) 0, 0); 3119 if (waited_pid < 0 && errno == EINTR) 3120 continue; 3121 if (waited_pid == command_pid) 3122 command_pid = -1; 3123 } 3124 3125 close (dev_null_fd); 3126 close (protocol_pipe[0]); 3127 close (protocol_pipe[1]); 3128 close (stderr_pipe[0]); 3129 close (stderr_pipe[1]); 3130 close (stdout_pipe[0]); 3131 close (stdout_pipe[1]); 3132 3133 free_args_and_return: 3134 /* Now free the arguments. */ 3135 { 3136 /* argument_vector[0] is a dummy argument, we don't mess with it. */ 3137 char **cp; 3138 for (cp = argument_vector + 1; 3139 cp < argument_vector + argument_count; 3140 ++cp) 3141 free (*cp); 3142 3143 argument_count = 1; 3144 } 3145 3146 /* Flush out any data not yet sent. */ 3147 set_block (buf_to_net); 3148 buf_flush (buf_to_net, 1); 3149 3150 return; 3151 } 3152 3153 #ifdef SERVER_FLOWCONTROL 3154 /* 3155 * Called by the child at convenient points in the server's execution for 3156 * the server child to block.. ie: when it has no locks active. 3157 */ 3158 void 3159 server_pause_check() 3160 { 3161 int paused = 0; 3162 char buf[1]; 3163 3164 while (read (flowcontrol_pipe[0], buf, 1) == 1) 3165 { 3166 if (*buf == 'S') /* Stop */ 3167 paused = 1; 3168 else if (*buf == 'G') /* Go */ 3169 paused = 0; 3170 else 3171 return; /* ??? */ 3172 } 3173 while (paused) { 3174 int numfds, numtocheck; 3175 fd_set fds; 3176 3177 FD_ZERO (&fds); 3178 FD_SET (flowcontrol_pipe[0], &fds); 3179 numtocheck = flowcontrol_pipe[0] + 1; 3180 3181 do { 3182 numfds = select (numtocheck, &fds, (fd_set *)0, 3183 (fd_set *)0, (struct timeval *)NULL); 3184 if (numfds < 0 3185 && errno != EINTR) 3186 { 3187 print_error (errno); 3188 return; 3189 } 3190 } while (numfds < 0); 3191 3192 if (FD_ISSET (flowcontrol_pipe[0], &fds)) 3193 { 3194 int got; 3195 3196 while ((got = read (flowcontrol_pipe[0], buf, 1)) == 1) 3197 { 3198 if (*buf == 'S') /* Stop */ 3199 paused = 1; 3200 else if (*buf == 'G') /* Go */ 3201 paused = 0; 3202 else 3203 return; /* ??? */ 3204 } 3205 3206 /* This assumes that we are using BSD or POSIX nonblocking 3207 I/O. System V nonblocking I/O returns zero if there is 3208 nothing to read. */ 3209 if (got == 0) 3210 error (1, 0, "flow control EOF"); 3211 if (got < 0 && ! blocking_error (errno)) 3212 { 3213 error (1, errno, "flow control read failed"); 3214 } 3215 } 3216 } 3217 } 3218 #endif /* SERVER_FLOWCONTROL */ 3219 3220 /* This variable commented in server.h. */ 3221 char *server_dir = NULL; 3222 3223 static void output_dir PROTO((char *, char *)); 3224 3225 static void 3226 output_dir (update_dir, repository) 3227 char *update_dir; 3228 char *repository; 3229 { 3230 if (server_dir != NULL) 3231 { 3232 buf_output0 (protocol, server_dir); 3233 buf_output0 (protocol, "/"); 3234 } 3235 if (update_dir[0] == '\0') 3236 buf_output0 (protocol, "."); 3237 else 3238 buf_output0 (protocol, update_dir); 3239 buf_output0 (protocol, "/\n"); 3240 buf_output0 (protocol, repository); 3241 buf_output0 (protocol, "/"); 3242 } 3243 3244 /* 3245 * Entries line that we are squirreling away to send to the client when 3246 * we are ready. 3247 */ 3248 static char *entries_line; 3249 3250 /* 3251 * File which has been Scratch_File'd, we are squirreling away that fact 3252 * to inform the client when we are ready. 3253 */ 3254 static char *scratched_file; 3255 3256 /* 3257 * The scratched_file will need to be removed as well as having its entry 3258 * removed. 3259 */ 3260 static int kill_scratched_file; 3261 3262 void 3263 server_register (name, version, timestamp, options, tag, date, conflict) 3264 char *name; 3265 char *version; 3266 char *timestamp; 3267 char *options; 3268 char *tag; 3269 char *date; 3270 char *conflict; 3271 { 3272 int len; 3273 3274 if (options == NULL) 3275 options = ""; 3276 3277 if (trace) 3278 { 3279 (void) fprintf (stderr, 3280 "%s-> server_register(%s, %s, %s, %s, %s, %s, %s)\n", 3281 CLIENT_SERVER_STR, 3282 name, version, timestamp ? timestamp : "", options, 3283 tag ? tag : "", date ? date : "", 3284 conflict ? conflict : ""); 3285 } 3286 3287 if (entries_line != NULL) 3288 { 3289 /* 3290 * If CVS decides to Register it more than once (which happens 3291 * on "cvs update foo/foo.c" where foo and foo.c are already 3292 * checked out), use the last of the entries lines Register'd. 3293 */ 3294 free (entries_line); 3295 } 3296 3297 /* 3298 * I have reports of Scratch_Entry and Register both happening, in 3299 * two different cases. Using the last one which happens is almost 3300 * surely correct; I haven't tracked down why they both happen (or 3301 * even verified that they are for the same file). 3302 */ 3303 if (scratched_file != NULL) 3304 { 3305 free (scratched_file); 3306 scratched_file = NULL; 3307 } 3308 3309 len = (strlen (name) + strlen (version) + strlen (options) + 80); 3310 if (tag) 3311 len += strlen (tag); 3312 if (date) 3313 len += strlen (date); 3314 3315 entries_line = xmalloc (len); 3316 sprintf (entries_line, "/%s/%s/", name, version); 3317 if (conflict != NULL) 3318 { 3319 strcat (entries_line, "+="); 3320 } 3321 strcat (entries_line, "/"); 3322 strcat (entries_line, options); 3323 strcat (entries_line, "/"); 3324 if (tag != NULL) 3325 { 3326 strcat (entries_line, "T"); 3327 strcat (entries_line, tag); 3328 } 3329 else if (date != NULL) 3330 { 3331 strcat (entries_line, "D"); 3332 strcat (entries_line, date); 3333 } 3334 } 3335 3336 void 3337 server_scratch (fname) 3338 char *fname; 3339 { 3340 /* 3341 * I have reports of Scratch_Entry and Register both happening, in 3342 * two different cases. Using the last one which happens is almost 3343 * surely correct; I haven't tracked down why they both happen (or 3344 * even verified that they are for the same file). 3345 */ 3346 if (entries_line != NULL) 3347 { 3348 free (entries_line); 3349 entries_line = NULL; 3350 } 3351 3352 if (scratched_file != NULL) 3353 { 3354 buf_output0 (protocol, 3355 "E CVS server internal error: duplicate Scratch_Entry\n"); 3356 buf_send_counted (protocol); 3357 return; 3358 } 3359 scratched_file = xstrdup (fname); 3360 kill_scratched_file = 1; 3361 } 3362 3363 void 3364 server_scratch_entry_only () 3365 { 3366 kill_scratched_file = 0; 3367 } 3368 3369 /* Print a new entries line, from a previous server_register. */ 3370 static void 3371 new_entries_line () 3372 { 3373 if (entries_line) 3374 { 3375 buf_output0 (protocol, entries_line); 3376 buf_output (protocol, "\n", 1); 3377 } 3378 else 3379 /* Return the error message as the Entries line. */ 3380 buf_output0 (protocol, 3381 "CVS server internal error: Register missing\n"); 3382 free (entries_line); 3383 entries_line = NULL; 3384 } 3385 3386 3387 static void 3388 serve_ci (arg) 3389 char *arg; 3390 { 3391 do_cvs_command ("commit", commit); 3392 } 3393 3394 static void 3395 checked_in_response (file, update_dir, repository) 3396 char *file; 3397 char *update_dir; 3398 char *repository; 3399 { 3400 if (supported_response ("Mode")) 3401 { 3402 struct stat sb; 3403 char *mode_string; 3404 3405 if ( CVS_STAT (file, &sb) < 0) 3406 { 3407 /* Not clear to me why the file would fail to exist, but it 3408 was happening somewhere in the testsuite. */ 3409 if (!existence_error (errno)) 3410 error (0, errno, "cannot stat %s", file); 3411 } 3412 else 3413 { 3414 buf_output0 (protocol, "Mode "); 3415 mode_string = mode_to_string (sb.st_mode); 3416 buf_output0 (protocol, mode_string); 3417 buf_output0 (protocol, "\n"); 3418 free (mode_string); 3419 } 3420 } 3421 3422 buf_output0 (protocol, "Checked-in "); 3423 output_dir (update_dir, repository); 3424 buf_output0 (protocol, file); 3425 buf_output (protocol, "\n", 1); 3426 new_entries_line (); 3427 } 3428 3429 void 3430 server_checked_in (file, update_dir, repository) 3431 char *file; 3432 char *update_dir; 3433 char *repository; 3434 { 3435 if (noexec) 3436 return; 3437 if (scratched_file != NULL && entries_line == NULL) 3438 { 3439 /* 3440 * This happens if we are now doing a "cvs remove" after a previous 3441 * "cvs add" (without a "cvs ci" in between). 3442 */ 3443 buf_output0 (protocol, "Remove-entry "); 3444 output_dir (update_dir, repository); 3445 buf_output0 (protocol, file); 3446 buf_output (protocol, "\n", 1); 3447 free (scratched_file); 3448 scratched_file = NULL; 3449 } 3450 else 3451 { 3452 checked_in_response (file, update_dir, repository); 3453 } 3454 buf_send_counted (protocol); 3455 } 3456 3457 void 3458 server_update_entries (file, update_dir, repository, updated) 3459 char *file; 3460 char *update_dir; 3461 char *repository; 3462 enum server_updated_arg4 updated; 3463 { 3464 if (noexec) 3465 return; 3466 if (updated == SERVER_UPDATED) 3467 checked_in_response (file, update_dir, repository); 3468 else 3469 { 3470 if (!supported_response ("New-entry")) 3471 return; 3472 buf_output0 (protocol, "New-entry "); 3473 output_dir (update_dir, repository); 3474 buf_output0 (protocol, file); 3475 buf_output (protocol, "\n", 1); 3476 new_entries_line (); 3477 } 3478 3479 buf_send_counted (protocol); 3480 } 3481 3482 static void 3483 serve_update (arg) 3484 char *arg; 3485 { 3486 do_cvs_command ("update", update); 3487 } 3488 3489 static void 3490 serve_diff (arg) 3491 char *arg; 3492 { 3493 do_cvs_command ("diff", diff); 3494 } 3495 3496 static void 3497 serve_log (arg) 3498 char *arg; 3499 { 3500 do_cvs_command ("log", cvslog); 3501 } 3502 3503 static void 3504 serve_add (arg) 3505 char *arg; 3506 { 3507 do_cvs_command ("add", add); 3508 } 3509 3510 static void 3511 serve_remove (arg) 3512 char *arg; 3513 { 3514 do_cvs_command ("remove", cvsremove); 3515 } 3516 3517 static void 3518 serve_status (arg) 3519 char *arg; 3520 { 3521 do_cvs_command ("status", cvsstatus); 3522 } 3523 3524 static void 3525 serve_rdiff (arg) 3526 char *arg; 3527 { 3528 do_cvs_command ("rdiff", patch); 3529 } 3530 3531 static void 3532 serve_tag (arg) 3533 char *arg; 3534 { 3535 do_cvs_command ("cvstag", cvstag); 3536 } 3537 3538 static void 3539 serve_rtag (arg) 3540 char *arg; 3541 { 3542 do_cvs_command ("rtag", rtag); 3543 } 3544 3545 static void 3546 serve_import (arg) 3547 char *arg; 3548 { 3549 do_cvs_command ("import", import); 3550 } 3551 3552 static void 3553 serve_admin (arg) 3554 char *arg; 3555 { 3556 do_cvs_command ("admin", admin); 3557 } 3558 3559 static void 3560 serve_history (arg) 3561 char *arg; 3562 { 3563 do_cvs_command ("history", history); 3564 } 3565 3566 static void 3567 serve_release (arg) 3568 char *arg; 3569 { 3570 do_cvs_command ("release", release); 3571 } 3572 3573 static void serve_watch_on PROTO ((char *)); 3574 3575 static void 3576 serve_watch_on (arg) 3577 char *arg; 3578 { 3579 do_cvs_command ("watch_on", watch_on); 3580 } 3581 3582 static void serve_watch_off PROTO ((char *)); 3583 3584 static void 3585 serve_watch_off (arg) 3586 char *arg; 3587 { 3588 do_cvs_command ("watch_off", watch_off); 3589 } 3590 3591 static void serve_watch_add PROTO ((char *)); 3592 3593 static void 3594 serve_watch_add (arg) 3595 char *arg; 3596 { 3597 do_cvs_command ("watch_add", watch_add); 3598 } 3599 3600 static void serve_watch_remove PROTO ((char *)); 3601 3602 static void 3603 serve_watch_remove (arg) 3604 char *arg; 3605 { 3606 do_cvs_command ("watch_remove", watch_remove); 3607 } 3608 3609 static void serve_watchers PROTO ((char *)); 3610 3611 static void 3612 serve_watchers (arg) 3613 char *arg; 3614 { 3615 do_cvs_command ("watchers", watchers); 3616 } 3617 3618 static void serve_editors PROTO ((char *)); 3619 3620 static void 3621 serve_editors (arg) 3622 char *arg; 3623 { 3624 do_cvs_command ("editors", editors); 3625 } 3626 3627 static int noop PROTO ((int, char **)); 3628 3629 static int 3630 noop (argc, argv) 3631 int argc; 3632 char **argv; 3633 { 3634 return 0; 3635 } 3636 3637 static void serve_noop PROTO ((char *)); 3638 3639 static void 3640 serve_noop (arg) 3641 char *arg; 3642 { 3643 do_cvs_command ("noop", noop); 3644 } 3645 3646 static void serve_init PROTO ((char *)); 3647 3648 static void 3649 serve_init (arg) 3650 char *arg; 3651 { 3652 if (!isabsolute (arg)) 3653 { 3654 if (alloc_pending (80 + strlen (arg))) 3655 sprintf (pending_error_text, 3656 "E Root %s must be an absolute pathname", arg); 3657 /* Fall through to do_cvs_command which will return the 3658 actual error. */ 3659 } 3660 set_local_cvsroot (arg); 3661 3662 do_cvs_command ("init", init); 3663 } 3664 3665 static void serve_annotate PROTO ((char *)); 3666 3667 static void 3668 serve_annotate (arg) 3669 char *arg; 3670 { 3671 do_cvs_command ("annotate", annotate); 3672 } 3673 3674 static void 3675 serve_co (arg) 3676 char *arg; 3677 { 3678 char *tempdir; 3679 int status; 3680 3681 if (print_pending_error ()) 3682 return; 3683 3684 if (!isdir (CVSADM)) 3685 { 3686 /* 3687 * The client has not sent a "Repository" line. Check out 3688 * into a pristine directory. 3689 */ 3690 tempdir = malloc (strlen (server_temp_dir) + 80); 3691 if (tempdir == NULL) 3692 { 3693 buf_output0 (buf_to_net, "E Out of memory\n"); 3694 return; 3695 } 3696 strcpy (tempdir, server_temp_dir); 3697 strcat (tempdir, "/checkout-dir"); 3698 status = mkdir_p (tempdir); 3699 if (status != 0 && status != EEXIST) 3700 { 3701 buf_output0 (buf_to_net, "E Cannot create "); 3702 buf_output0 (buf_to_net, tempdir); 3703 buf_append_char (buf_to_net, '\n'); 3704 print_error (errno); 3705 free (tempdir); 3706 return; 3707 } 3708 3709 if ( CVS_CHDIR (tempdir) < 0) 3710 { 3711 buf_output0 (buf_to_net, "E Cannot change to directory "); 3712 buf_output0 (buf_to_net, tempdir); 3713 buf_append_char (buf_to_net, '\n'); 3714 print_error (errno); 3715 free (tempdir); 3716 return; 3717 } 3718 free (tempdir); 3719 } 3720 3721 /* Compensate for server_export()'s setting of command_name. 3722 * 3723 * [It probably doesn't matter if do_cvs_command() gets "export" 3724 * or "checkout", but we ought to be accurate where possible.] 3725 */ 3726 do_cvs_command ((strcmp (command_name, "export") == 0) ? 3727 "export" : "checkout", 3728 checkout); 3729 } 3730 3731 static void 3732 serve_export (arg) 3733 char *arg; 3734 { 3735 /* Tell checkout() to behave like export not checkout. */ 3736 command_name = "export"; 3737 serve_co (arg); 3738 } 3739 3740 void 3741 server_copy_file (file, update_dir, repository, newfile) 3742 char *file; 3743 char *update_dir; 3744 char *repository; 3745 char *newfile; 3746 { 3747 /* At least for now, our practice is to have the server enforce 3748 noexec for the repository and the client enforce it for the 3749 working directory. This might want more thought, and/or 3750 documentation in cvsclient.texi (other responses do it 3751 differently). */ 3752 3753 if (!supported_response ("Copy-file")) 3754 return; 3755 buf_output0 (protocol, "Copy-file "); 3756 output_dir (update_dir, repository); 3757 buf_output0 (protocol, file); 3758 buf_output0 (protocol, "\n"); 3759 buf_output0 (protocol, newfile); 3760 buf_output0 (protocol, "\n"); 3761 } 3762 3763 /* See server.h for description. */ 3764 3765 void 3766 server_modtime (finfo, vers_ts) 3767 struct file_info *finfo; 3768 Vers_TS *vers_ts; 3769 { 3770 char date[MAXDATELEN]; 3771 char outdate[MAXDATELEN]; 3772 3773 assert (vers_ts->vn_rcs != NULL); 3774 3775 if (!supported_response ("Mod-time")) 3776 return; 3777 3778 if (RCS_getrevtime (finfo->rcs, vers_ts->vn_rcs, date, 0) == (time_t) -1) 3779 /* FIXME? should we be printing some kind of warning? For one 3780 thing I'm not 100% sure whether this happens in non-error 3781 circumstances. */ 3782 return; 3783 date_to_internet (outdate, date); 3784 buf_output0 (protocol, "Mod-time "); 3785 buf_output0 (protocol, outdate); 3786 buf_output0 (protocol, "\n"); 3787 } 3788 3789 /* See server.h for description. */ 3790 3791 #if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__) 3792 /* Need to prototype because mode_t might be smaller than int. */ 3793 void 3794 server_updated ( 3795 struct file_info *finfo, 3796 Vers_TS *vers, 3797 enum server_updated_arg4 updated, 3798 mode_t mode, 3799 unsigned char *checksum, 3800 struct buffer *filebuf) 3801 #else 3802 void 3803 server_updated (finfo, vers, updated, mode, checksum, filebuf) 3804 struct file_info *finfo; 3805 Vers_TS *vers; 3806 enum server_updated_arg4 updated; 3807 mode_t mode; 3808 unsigned char *checksum; 3809 struct buffer *filebuf; 3810 #endif 3811 { 3812 if (noexec) 3813 { 3814 /* Hmm, maybe if we did the same thing for entries_file, we 3815 could get rid of the kludges in server_register and 3816 server_scratch which refrain from warning if both 3817 Scratch_Entry and Register get called. Maybe. */ 3818 if (scratched_file) 3819 { 3820 free (scratched_file); 3821 scratched_file = NULL; 3822 } 3823 return; 3824 } 3825 3826 if (entries_line != NULL && scratched_file == NULL) 3827 { 3828 FILE *f; 3829 struct buffer_data *list, *last; 3830 unsigned long size; 3831 char size_text[80]; 3832 3833 /* The contents of the file will be in one of filebuf, 3834 list/last, or here. */ 3835 unsigned char *file; 3836 size_t file_allocated; 3837 size_t file_used; 3838 3839 if (filebuf != NULL) 3840 { 3841 size = buf_length (filebuf); 3842 if (mode == (mode_t) -1) 3843 error (1, 0, "\ 3844 CVS server internal error: no mode in server_updated"); 3845 } 3846 else 3847 { 3848 struct stat sb; 3849 3850 if ( CVS_STAT (finfo->file, &sb) < 0) 3851 { 3852 if (existence_error (errno)) 3853 { 3854 /* If we have a sticky tag for a branch on which 3855 the file is dead, and cvs update the directory, 3856 it gets a T_CHECKOUT but no file. So in this 3857 case just forget the whole thing. */ 3858 free (entries_line); 3859 entries_line = NULL; 3860 goto done; 3861 } 3862 error (1, errno, "reading %s", finfo->fullname); 3863 } 3864 size = sb.st_size; 3865 if (mode == (mode_t) -1) 3866 { 3867 /* FIXME: When we check out files the umask of the 3868 server (set in .bashrc if rsh is in use) affects 3869 what mode we send, and it shouldn't. */ 3870 mode = sb.st_mode; 3871 } 3872 } 3873 3874 if (checksum != NULL) 3875 { 3876 static int checksum_supported = -1; 3877 3878 if (checksum_supported == -1) 3879 { 3880 checksum_supported = supported_response ("Checksum"); 3881 } 3882 3883 if (checksum_supported) 3884 { 3885 int i; 3886 char buf[3]; 3887 3888 buf_output0 (protocol, "Checksum "); 3889 for (i = 0; i < 16; i++) 3890 { 3891 sprintf (buf, "%02x", (unsigned int) checksum[i]); 3892 buf_output0 (protocol, buf); 3893 } 3894 buf_append_char (protocol, '\n'); 3895 } 3896 } 3897 3898 if (updated == SERVER_UPDATED) 3899 { 3900 Node *node; 3901 Entnode *entnode; 3902 3903 if (!(supported_response ("Created") 3904 && supported_response ("Update-existing"))) 3905 buf_output0 (protocol, "Updated "); 3906 else 3907 { 3908 assert (vers != NULL); 3909 if (vers->ts_user == NULL) 3910 buf_output0 (protocol, "Created "); 3911 else 3912 buf_output0 (protocol, "Update-existing "); 3913 } 3914 3915 /* Now munge the entries to say that the file is unmodified, 3916 in case we end up processing it again (e.g. modules3-6 3917 in the testsuite). */ 3918 node = findnode_fn (finfo->entries, finfo->file); 3919 entnode = (Entnode *)node->data; 3920 free (entnode->timestamp); 3921 entnode->timestamp = xstrdup ("="); 3922 } 3923 else if (updated == SERVER_MERGED) 3924 buf_output0 (protocol, "Merged "); 3925 else if (updated == SERVER_PATCHED) 3926 buf_output0 (protocol, "Patched "); 3927 else if (updated == SERVER_RCS_DIFF) 3928 buf_output0 (protocol, "Rcs-diff "); 3929 else 3930 abort (); 3931 output_dir (finfo->update_dir, finfo->repository); 3932 buf_output0 (protocol, finfo->file); 3933 buf_output (protocol, "\n", 1); 3934 3935 new_entries_line (); 3936 3937 { 3938 char *mode_string; 3939 3940 mode_string = mode_to_string (mode); 3941 buf_output0 (protocol, mode_string); 3942 buf_output0 (protocol, "\n"); 3943 free (mode_string); 3944 } 3945 3946 list = last = NULL; 3947 3948 file = NULL; 3949 file_allocated = 0; 3950 file_used = 0; 3951 3952 if (size > 0) 3953 { 3954 /* Throughout this section we use binary mode to read the 3955 file we are sending. The client handles any line ending 3956 translation if necessary. */ 3957 3958 if (file_gzip_level 3959 /* 3960 * For really tiny files, the gzip process startup 3961 * time will outweigh the compression savings. This 3962 * might be computable somehow; using 100 here is just 3963 * a first approximation. 3964 */ 3965 && size > 100) 3966 { 3967 /* Basing this routine on read_and_gzip is not a 3968 high-performance approach. But it seems easier 3969 to code than the alternative (and less 3970 vulnerable to subtle bugs). Given that this feature 3971 is mainly for compatibility, that is the better 3972 tradeoff. */ 3973 3974 int fd; 3975 3976 /* Callers must avoid passing us a buffer if 3977 file_gzip_level is set. We could handle this case, 3978 but it's not worth it since this case never arises 3979 with a current client and server. */ 3980 if (filebuf != NULL) 3981 error (1, 0, "\ 3982 CVS server internal error: unhandled case in server_updated"); 3983 3984 fd = CVS_OPEN (finfo->file, O_RDONLY | OPEN_BINARY, 0); 3985 if (fd < 0) 3986 error (1, errno, "reading %s", finfo->fullname); 3987 if (read_and_gzip (fd, finfo->fullname, &file, 3988 &file_allocated, &file_used, 3989 file_gzip_level)) 3990 error (1, 0, "aborting due to compression error"); 3991 size = file_used; 3992 if (close (fd) < 0) 3993 error (1, errno, "reading %s", finfo->fullname); 3994 /* Prepending length with "z" is flag for using gzip here. */ 3995 buf_output0 (protocol, "z"); 3996 } 3997 else if (filebuf == NULL) 3998 { 3999 long status; 4000 4001 f = CVS_FOPEN (finfo->file, "rb"); 4002 if (f == NULL) 4003 error (1, errno, "reading %s", finfo->fullname); 4004 status = buf_read_file (f, size, &list, &last); 4005 if (status == -2) 4006 (*protocol->memory_error) (protocol); 4007 else if (status != 0) 4008 error (1, ferror (f) ? errno : 0, "reading %s", 4009 finfo->fullname); 4010 if (fclose (f) == EOF) 4011 error (1, errno, "reading %s", finfo->fullname); 4012 } 4013 } 4014 4015 sprintf (size_text, "%lu\n", size); 4016 buf_output0 (protocol, size_text); 4017 4018 if (file != NULL) 4019 { 4020 buf_output (protocol, file, file_used); 4021 free (file); 4022 file = NULL; 4023 } 4024 else if (filebuf == NULL) 4025 buf_append_data (protocol, list, last); 4026 else 4027 { 4028 buf_append_buffer (protocol, filebuf); 4029 buf_free (filebuf); 4030 } 4031 /* Note we only send a newline here if the file ended with one. */ 4032 4033 /* 4034 * Avoid using up too much disk space for temporary files. 4035 * A file which does not exist indicates that the file is up-to-date, 4036 * which is now the case. If this is SERVER_MERGED, the file is 4037 * not up-to-date, and we indicate that by leaving the file there. 4038 * I'm thinking of cases like "cvs update foo/foo.c foo". 4039 */ 4040 if ((updated == SERVER_UPDATED 4041 || updated == SERVER_PATCHED 4042 || updated == SERVER_RCS_DIFF) 4043 && filebuf == NULL 4044 /* But if we are joining, we'll need the file when we call 4045 join_file. */ 4046 && !joining ()) 4047 { 4048 if (CVS_UNLINK (finfo->file) < 0) 4049 error (0, errno, "cannot remove temp file for %s", 4050 finfo->fullname); 4051 } 4052 } 4053 else if (scratched_file != NULL && entries_line == NULL) 4054 { 4055 if (strcmp (scratched_file, finfo->file) != 0) 4056 error (1, 0, 4057 "CVS server internal error: `%s' vs. `%s' scratched", 4058 scratched_file, 4059 finfo->file); 4060 free (scratched_file); 4061 scratched_file = NULL; 4062 4063 if (kill_scratched_file) 4064 buf_output0 (protocol, "Removed "); 4065 else 4066 buf_output0 (protocol, "Remove-entry "); 4067 output_dir (finfo->update_dir, finfo->repository); 4068 buf_output0 (protocol, finfo->file); 4069 buf_output (protocol, "\n", 1); 4070 } 4071 else if (scratched_file == NULL && entries_line == NULL) 4072 { 4073 /* 4074 * This can happen with death support if we were processing 4075 * a dead file in a checkout. 4076 */ 4077 } 4078 else 4079 error (1, 0, 4080 "CVS server internal error: Register *and* Scratch_Entry.\n"); 4081 buf_send_counted (protocol); 4082 done:; 4083 } 4084 4085 /* Return whether we should send patches in RCS format. */ 4086 4087 int 4088 server_use_rcs_diff () 4089 { 4090 return supported_response ("Rcs-diff"); 4091 } 4092 4093 void 4094 server_set_entstat (update_dir, repository) 4095 char *update_dir; 4096 char *repository; 4097 { 4098 static int set_static_supported = -1; 4099 if (set_static_supported == -1) 4100 set_static_supported = supported_response ("Set-static-directory"); 4101 if (!set_static_supported) return; 4102 4103 buf_output0 (protocol, "Set-static-directory "); 4104 output_dir (update_dir, repository); 4105 buf_output0 (protocol, "\n"); 4106 buf_send_counted (protocol); 4107 } 4108 4109 void 4110 server_clear_entstat (update_dir, repository) 4111 char *update_dir; 4112 char *repository; 4113 { 4114 static int clear_static_supported = -1; 4115 if (clear_static_supported == -1) 4116 clear_static_supported = supported_response ("Clear-static-directory"); 4117 if (!clear_static_supported) return; 4118 4119 if (noexec) 4120 return; 4121 4122 buf_output0 (protocol, "Clear-static-directory "); 4123 output_dir (update_dir, repository); 4124 buf_output0 (protocol, "\n"); 4125 buf_send_counted (protocol); 4126 } 4127 4128 void 4129 server_set_sticky (update_dir, repository, tag, date, nonbranch) 4130 char *update_dir; 4131 char *repository; 4132 char *tag; 4133 char *date; 4134 int nonbranch; 4135 { 4136 static int set_sticky_supported = -1; 4137 4138 assert (update_dir != NULL); 4139 4140 if (set_sticky_supported == -1) 4141 set_sticky_supported = supported_response ("Set-sticky"); 4142 if (!set_sticky_supported) return; 4143 4144 if (noexec) 4145 return; 4146 4147 if (tag == NULL && date == NULL) 4148 { 4149 buf_output0 (protocol, "Clear-sticky "); 4150 output_dir (update_dir, repository); 4151 buf_output0 (protocol, "\n"); 4152 } 4153 else 4154 { 4155 buf_output0 (protocol, "Set-sticky "); 4156 output_dir (update_dir, repository); 4157 buf_output0 (protocol, "\n"); 4158 if (tag != NULL) 4159 { 4160 if (nonbranch) 4161 buf_output0 (protocol, "N"); 4162 else 4163 buf_output0 (protocol, "T"); 4164 buf_output0 (protocol, tag); 4165 } 4166 else 4167 { 4168 buf_output0 (protocol, "D"); 4169 buf_output0 (protocol, date); 4170 } 4171 buf_output0 (protocol, "\n"); 4172 } 4173 buf_send_counted (protocol); 4174 } 4175 4176 struct template_proc_data 4177 { 4178 char *update_dir; 4179 char *repository; 4180 }; 4181 4182 /* Here as a static until we get around to fixing Parse_Info to pass along 4183 a void * for it. */ 4184 static struct template_proc_data *tpd; 4185 4186 static int 4187 template_proc (repository, template) 4188 char *repository; 4189 char *template; 4190 { 4191 FILE *fp; 4192 char buf[1024]; 4193 size_t n; 4194 struct stat sb; 4195 struct template_proc_data *data = tpd; 4196 4197 if (!supported_response ("Template")) 4198 /* Might want to warn the user that the rcsinfo feature won't work. */ 4199 return 0; 4200 buf_output0 (protocol, "Template "); 4201 output_dir (data->update_dir, data->repository); 4202 buf_output0 (protocol, "\n"); 4203 4204 fp = CVS_FOPEN (template, "rb"); 4205 if (fp == NULL) 4206 { 4207 error (0, errno, "Couldn't open rcsinfo template file %s", template); 4208 return 1; 4209 } 4210 if (fstat (fileno (fp), &sb) < 0) 4211 { 4212 error (0, errno, "cannot stat rcsinfo template file %s", template); 4213 return 1; 4214 } 4215 sprintf (buf, "%ld\n", (long) sb.st_size); 4216 buf_output0 (protocol, buf); 4217 while (!feof (fp)) 4218 { 4219 n = fread (buf, 1, sizeof buf, fp); 4220 buf_output (protocol, buf, n); 4221 if (ferror (fp)) 4222 { 4223 error (0, errno, "cannot read rcsinfo template file %s", template); 4224 (void) fclose (fp); 4225 return 1; 4226 } 4227 } 4228 if (fclose (fp) < 0) 4229 error (0, errno, "cannot close rcsinfo template file %s", template); 4230 return 0; 4231 } 4232 4233 void 4234 server_template (update_dir, repository) 4235 char *update_dir; 4236 char *repository; 4237 { 4238 struct template_proc_data data; 4239 data.update_dir = update_dir; 4240 data.repository = repository; 4241 tpd = &data; 4242 (void) Parse_Info (CVSROOTADM_RCSINFO, repository, template_proc, 1); 4243 } 4244 4245 static void 4246 serve_gzip_contents (arg) 4247 char *arg; 4248 { 4249 int level; 4250 level = atoi (arg); 4251 if (level == 0) 4252 level = 6; 4253 file_gzip_level = level; 4254 } 4255 4256 static void 4257 serve_gzip_stream (arg) 4258 char *arg; 4259 { 4260 int level; 4261 level = atoi (arg); 4262 if (level == 0) 4263 level = 6; 4264 4265 /* All further communication with the client will be compressed. */ 4266 4267 buf_to_net = compress_buffer_initialize (buf_to_net, 0, level, 4268 buf_to_net->memory_error); 4269 buf_from_net = compress_buffer_initialize (buf_from_net, 1, level, 4270 buf_from_net->memory_error); 4271 } 4272 4273 /* Tell the client about RCS options set in CVSROOT/cvswrappers. */ 4274 static void 4275 serve_wrapper_sendme_rcs_options (arg) 4276 char *arg; 4277 { 4278 /* Actually, this is kind of sdrawkcab-ssa: the client wants 4279 * verbatim lines from a cvswrappers file, but the server has 4280 * already parsed the cvswrappers file into the wrap_list struct. 4281 * Therefore, the server loops over wrap_list, unparsing each 4282 * entry before sending it. 4283 */ 4284 char *wrapper_line = NULL; 4285 4286 wrap_setup (); 4287 4288 for (wrap_unparse_rcs_options (&wrapper_line, 1); 4289 wrapper_line; 4290 wrap_unparse_rcs_options (&wrapper_line, 0)) 4291 { 4292 buf_output0 (buf_to_net, "Wrapper-rcsOption "); 4293 buf_output0 (buf_to_net, wrapper_line); 4294 buf_output0 (buf_to_net, "\012");; 4295 free (wrapper_line); 4296 } 4297 4298 buf_output0 (buf_to_net, "ok\012"); 4299 4300 /* The client is waiting for us, so we better send the data now. */ 4301 buf_flush (buf_to_net, 1); 4302 } 4303 4304 4305 static void 4306 serve_ignore (arg) 4307 char *arg; 4308 { 4309 /* 4310 * Just ignore this command. This is used to support the 4311 * update-patches command, which is not a real command, but a signal 4312 * to the client that update will accept the -u argument. 4313 */ 4314 } 4315 4316 static int 4317 expand_proc (pargc, argv, where, mwhere, mfile, shorten, 4318 local_specified, omodule, msg) 4319 int *pargc; 4320 char **argv; 4321 char *where; 4322 char *mwhere; 4323 char *mfile; 4324 int shorten; 4325 int local_specified; 4326 char *omodule; 4327 char *msg; 4328 { 4329 int i; 4330 char *dir = argv[0]; 4331 4332 /* If mwhere has been specified, the thing we're expanding is a 4333 module -- just return its name so the client will ask for the 4334 right thing later. If it is an alias or a real directory, 4335 mwhere will not be set, so send out the appropriate 4336 expansion. */ 4337 4338 if (mwhere != NULL) 4339 { 4340 buf_output0 (buf_to_net, "Module-expansion "); 4341 if (server_dir != NULL) 4342 { 4343 buf_output0 (buf_to_net, server_dir); 4344 buf_output0 (buf_to_net, "/"); 4345 } 4346 buf_output0 (buf_to_net, mwhere); 4347 if (mfile != NULL) 4348 { 4349 buf_append_char (buf_to_net, '/'); 4350 buf_output0 (buf_to_net, mfile); 4351 } 4352 buf_append_char (buf_to_net, '\n'); 4353 } 4354 else 4355 { 4356 /* We may not need to do this anymore -- check the definition 4357 of aliases before removing */ 4358 if (*pargc == 1) 4359 { 4360 buf_output0 (buf_to_net, "Module-expansion "); 4361 if (server_dir != NULL) 4362 { 4363 buf_output0 (buf_to_net, server_dir); 4364 buf_output0 (buf_to_net, "/"); 4365 } 4366 buf_output0 (buf_to_net, dir); 4367 buf_append_char (buf_to_net, '\n'); 4368 } 4369 else 4370 { 4371 for (i = 1; i < *pargc; ++i) 4372 { 4373 buf_output0 (buf_to_net, "Module-expansion "); 4374 if (server_dir != NULL) 4375 { 4376 buf_output0 (buf_to_net, server_dir); 4377 buf_output0 (buf_to_net, "/"); 4378 } 4379 buf_output0 (buf_to_net, dir); 4380 buf_append_char (buf_to_net, '/'); 4381 buf_output0 (buf_to_net, argv[i]); 4382 buf_append_char (buf_to_net, '\n'); 4383 } 4384 } 4385 } 4386 return 0; 4387 } 4388 4389 static void 4390 serve_expand_modules (arg) 4391 char *arg; 4392 { 4393 int i; 4394 int err; 4395 DBM *db; 4396 err = 0; 4397 4398 server_expanding = 1; 4399 db = open_module (); 4400 for (i = 1; i < argument_count; i++) 4401 err += do_module (db, argument_vector[i], 4402 CHECKOUT, "Updating", expand_proc, 4403 NULL, 0, 0, 0, 4404 (char *) NULL); 4405 close_module (db); 4406 server_expanding = 0; 4407 { 4408 /* argument_vector[0] is a dummy argument, we don't mess with it. */ 4409 char **cp; 4410 for (cp = argument_vector + 1; 4411 cp < argument_vector + argument_count; 4412 ++cp) 4413 free (*cp); 4414 4415 argument_count = 1; 4416 } 4417 if (err) 4418 /* We will have printed an error message already. */ 4419 buf_output0 (buf_to_net, "error \n"); 4420 else 4421 buf_output0 (buf_to_net, "ok\n"); 4422 4423 /* The client is waiting for the module expansions, so we must 4424 send the output now. */ 4425 buf_flush (buf_to_net, 1); 4426 } 4427 4428 void 4429 server_prog (dir, name, which) 4430 char *dir; 4431 char *name; 4432 enum progs which; 4433 { 4434 if (!supported_response ("Set-checkin-prog")) 4435 { 4436 buf_output0 (buf_to_net, "E \ 4437 warning: this client does not support -i or -u flags in the modules file.\n"); 4438 return; 4439 } 4440 switch (which) 4441 { 4442 case PROG_CHECKIN: 4443 buf_output0 (buf_to_net, "Set-checkin-prog "); 4444 break; 4445 case PROG_UPDATE: 4446 buf_output0 (buf_to_net, "Set-update-prog "); 4447 break; 4448 } 4449 buf_output0 (buf_to_net, dir); 4450 buf_append_char (buf_to_net, '\n'); 4451 buf_output0 (buf_to_net, name); 4452 buf_append_char (buf_to_net, '\n'); 4453 } 4454 4455 static void 4456 serve_checkin_prog (arg) 4457 char *arg; 4458 { 4459 FILE *f; 4460 f = CVS_FOPEN (CVSADM_CIPROG, "w+"); 4461 if (f == NULL) 4462 { 4463 pending_error = errno; 4464 if (alloc_pending (80 + strlen (CVSADM_CIPROG))) 4465 sprintf (pending_error_text, "E cannot open %s", CVSADM_CIPROG); 4466 return; 4467 } 4468 if (fprintf (f, "%s\n", arg) < 0) 4469 { 4470 pending_error = errno; 4471 if (alloc_pending (80 + strlen (CVSADM_CIPROG))) 4472 sprintf (pending_error_text, 4473 "E cannot write to %s", CVSADM_CIPROG); 4474 return; 4475 } 4476 if (fclose (f) == EOF) 4477 { 4478 pending_error = errno; 4479 if (alloc_pending (80 + strlen (CVSADM_CIPROG))) 4480 sprintf (pending_error_text, "E cannot close %s", CVSADM_CIPROG); 4481 return; 4482 } 4483 } 4484 4485 static void 4486 serve_update_prog (arg) 4487 char *arg; 4488 { 4489 FILE *f; 4490 4491 /* Before we do anything we need to make sure we are not in readonly 4492 mode. */ 4493 if (!check_command_legal_p ("commit")) 4494 { 4495 /* I might be willing to make this a warning, except we lack the 4496 machinery to do so. */ 4497 if (alloc_pending (80)) 4498 sprintf (pending_error_text, "\ 4499 E Flag -u in modules not allowed in readonly mode"); 4500 return; 4501 } 4502 4503 f = CVS_FOPEN (CVSADM_UPROG, "w+"); 4504 if (f == NULL) 4505 { 4506 pending_error = errno; 4507 if (alloc_pending (80 + strlen (CVSADM_UPROG))) 4508 sprintf (pending_error_text, "E cannot open %s", CVSADM_UPROG); 4509 return; 4510 } 4511 if (fprintf (f, "%s\n", arg) < 0) 4512 { 4513 pending_error = errno; 4514 if (alloc_pending (80 + strlen (CVSADM_UPROG))) 4515 sprintf (pending_error_text, "E cannot write to %s", CVSADM_UPROG); 4516 return; 4517 } 4518 if (fclose (f) == EOF) 4519 { 4520 pending_error = errno; 4521 if (alloc_pending (80 + strlen (CVSADM_UPROG))) 4522 sprintf (pending_error_text, "E cannot close %s", CVSADM_UPROG); 4523 return; 4524 } 4525 } 4526 4527 static void serve_valid_requests PROTO((char *arg)); 4528 4529 #endif /* SERVER_SUPPORT */ 4530 #if defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT) 4531 4532 /* 4533 * Parts of this table are shared with the client code, 4534 * but the client doesn't need to know about the handler 4535 * functions. 4536 */ 4537 4538 struct request requests[] = 4539 { 4540 #ifdef SERVER_SUPPORT 4541 #define REQ_LINE(n, f, s) {n, f, s} 4542 #else 4543 #define REQ_LINE(n, f, s) {n, s} 4544 #endif 4545 4546 REQ_LINE("Root", serve_root, RQ_ESSENTIAL | RQ_ROOTLESS), 4547 REQ_LINE("Valid-responses", serve_valid_responses, 4548 RQ_ESSENTIAL | RQ_ROOTLESS), 4549 REQ_LINE("valid-requests", serve_valid_requests, 4550 RQ_ESSENTIAL | RQ_ROOTLESS), 4551 REQ_LINE("Repository", serve_repository, 0), 4552 REQ_LINE("Directory", serve_directory, RQ_ESSENTIAL), 4553 REQ_LINE("Max-dotdot", serve_max_dotdot, 0), 4554 REQ_LINE("Static-directory", serve_static_directory, 0), 4555 REQ_LINE("Sticky", serve_sticky, 0), 4556 REQ_LINE("Checkin-prog", serve_checkin_prog, 0), 4557 REQ_LINE("Update-prog", serve_update_prog, 0), 4558 REQ_LINE("Entry", serve_entry, RQ_ESSENTIAL), 4559 REQ_LINE("Kopt", serve_kopt, 0), 4560 REQ_LINE("Checkin-time", serve_checkin_time, 0), 4561 REQ_LINE("Modified", serve_modified, RQ_ESSENTIAL), 4562 REQ_LINE("Is-modified", serve_is_modified, 0), 4563 4564 /* The client must send this request to interoperate with CVS 1.5 4565 through 1.9 servers. The server must support it (although it can 4566 be and is a noop) to interoperate with CVS 1.5 to 1.9 clients. */ 4567 REQ_LINE("UseUnchanged", serve_enable_unchanged, RQ_ENABLEME | RQ_ROOTLESS), 4568 4569 REQ_LINE("Unchanged", serve_unchanged, RQ_ESSENTIAL), 4570 REQ_LINE("Notify", serve_notify, 0), 4571 REQ_LINE("Questionable", serve_questionable, 0), 4572 REQ_LINE("Case", serve_case, 0), 4573 REQ_LINE("Argument", serve_argument, RQ_ESSENTIAL), 4574 REQ_LINE("Argumentx", serve_argumentx, RQ_ESSENTIAL), 4575 REQ_LINE("Global_option", serve_global_option, 0), 4576 REQ_LINE("Gzip-stream", serve_gzip_stream, 0), 4577 REQ_LINE("wrapper-sendme-rcsOptions", 4578 serve_wrapper_sendme_rcs_options, 4579 0), 4580 REQ_LINE("Set", serve_set, RQ_ROOTLESS), 4581 #ifdef ENCRYPTION 4582 # ifdef HAVE_KERBEROS 4583 REQ_LINE("Kerberos-encrypt", serve_kerberos_encrypt, 0), 4584 # endif 4585 # ifdef HAVE_GSSAPI 4586 REQ_LINE("Gssapi-encrypt", serve_gssapi_encrypt, 0), 4587 # endif 4588 #endif 4589 #ifdef HAVE_GSSAPI 4590 REQ_LINE("Gssapi-authenticate", serve_gssapi_authenticate, 0), 4591 #endif 4592 REQ_LINE("expand-modules", serve_expand_modules, 0), 4593 REQ_LINE("ci", serve_ci, RQ_ESSENTIAL), 4594 REQ_LINE("co", serve_co, RQ_ESSENTIAL), 4595 REQ_LINE("update", serve_update, RQ_ESSENTIAL), 4596 REQ_LINE("diff", serve_diff, 0), 4597 REQ_LINE("log", serve_log, 0), 4598 REQ_LINE("add", serve_add, 0), 4599 REQ_LINE("remove", serve_remove, 0), 4600 REQ_LINE("update-patches", serve_ignore, 0), 4601 REQ_LINE("gzip-file-contents", serve_gzip_contents, 0), 4602 REQ_LINE("status", serve_status, 0), 4603 REQ_LINE("rdiff", serve_rdiff, 0), 4604 REQ_LINE("tag", serve_tag, 0), 4605 REQ_LINE("rtag", serve_rtag, 0), 4606 REQ_LINE("import", serve_import, 0), 4607 REQ_LINE("admin", serve_admin, 0), 4608 REQ_LINE("export", serve_export, 0), 4609 REQ_LINE("history", serve_history, 0), 4610 REQ_LINE("release", serve_release, 0), 4611 REQ_LINE("watch-on", serve_watch_on, 0), 4612 REQ_LINE("watch-off", serve_watch_off, 0), 4613 REQ_LINE("watch-add", serve_watch_add, 0), 4614 REQ_LINE("watch-remove", serve_watch_remove, 0), 4615 REQ_LINE("watchers", serve_watchers, 0), 4616 REQ_LINE("editors", serve_editors, 0), 4617 REQ_LINE("init", serve_init, RQ_ROOTLESS), 4618 REQ_LINE("annotate", serve_annotate, 0), 4619 REQ_LINE("noop", serve_noop, 0), 4620 REQ_LINE(NULL, NULL, 0) 4621 4622 #undef REQ_LINE 4623 }; 4624 4625 #endif /* SERVER_SUPPORT or CLIENT_SUPPORT */ 4626 #ifdef SERVER_SUPPORT 4627 4628 static void 4629 serve_valid_requests (arg) 4630 char *arg; 4631 { 4632 struct request *rq; 4633 if (print_pending_error ()) 4634 return; 4635 buf_output0 (buf_to_net, "Valid-requests"); 4636 for (rq = requests; rq->name != NULL; rq++) 4637 { 4638 if (rq->func != NULL) 4639 { 4640 buf_append_char (buf_to_net, ' '); 4641 buf_output0 (buf_to_net, rq->name); 4642 } 4643 } 4644 buf_output0 (buf_to_net, "\nok\n"); 4645 4646 /* The client is waiting for the list of valid requests, so we 4647 must send the output now. */ 4648 buf_flush (buf_to_net, 1); 4649 } 4650 4651 #ifdef sun 4652 /* 4653 * Delete temporary files. SIG is the signal making this happen, or 4654 * 0 if not called as a result of a signal. 4655 */ 4656 static int command_pid_is_dead; 4657 static void wait_sig (sig) 4658 int sig; 4659 { 4660 int status; 4661 int save_errno = errno; 4662 4663 pid_t r = wait (&status); 4664 if (r == command_pid) 4665 command_pid_is_dead++; 4666 errno = save_errno; 4667 } 4668 #endif 4669 4670 void 4671 server_cleanup (sig) 4672 int sig; 4673 { 4674 /* Do "rm -rf" on the temp directory. */ 4675 int status; 4676 int save_noexec; 4677 4678 if (buf_to_net != NULL) 4679 { 4680 /* FIXME: If this is not the final call from server, this 4681 could deadlock, because the client might be blocked writing 4682 to us. This should not be a problem in practice, because 4683 we do not generate much output when the client is not 4684 waiting for it. */ 4685 set_block (buf_to_net); 4686 buf_flush (buf_to_net, 1); 4687 4688 /* The calls to buf_shutdown are currently only meaningful 4689 when we are using compression. First we shut down 4690 BUF_FROM_NET. That will pick up the checksum generated 4691 when the client shuts down its buffer. Then, after we have 4692 generated any final output, we shut down BUF_TO_NET. */ 4693 4694 status = buf_shutdown (buf_from_net); 4695 if (status != 0) 4696 { 4697 error (0, status, "shutting down buffer from client"); 4698 buf_flush (buf_to_net, 1); 4699 } 4700 } 4701 4702 if (dont_delete_temp) 4703 { 4704 if (buf_to_net != NULL) 4705 (void) buf_shutdown (buf_to_net); 4706 return; 4707 } 4708 4709 /* What a bogus kludge. This disgusting code makes all kinds of 4710 assumptions about SunOS, and is only for a bug in that system. 4711 So only enable it on Suns. */ 4712 #ifdef sun 4713 if (command_pid > 0) 4714 { 4715 /* To avoid crashes on SunOS due to bugs in SunOS tmpfs 4716 triggered by the use of rename() in RCS, wait for the 4717 subprocess to die. Unfortunately, this means draining output 4718 while waiting for it to unblock the signal we sent it. Yuck! */ 4719 int status; 4720 pid_t r; 4721 4722 signal (SIGCHLD, wait_sig); 4723 if (sig) 4724 /* Perhaps SIGTERM would be more correct. But the child 4725 process will delay the SIGINT delivery until its own 4726 children have exited. */ 4727 kill (command_pid, SIGINT); 4728 /* The caller may also have sent a signal to command_pid, so 4729 always try waiting. First, though, check and see if it's still 4730 there.... */ 4731 do_waitpid: 4732 r = waitpid (command_pid, &status, WNOHANG); 4733 if (r == 0) 4734 ; 4735 else if (r == command_pid) 4736 command_pid_is_dead++; 4737 else if (r == -1) 4738 switch (errno) 4739 { 4740 case ECHILD: 4741 command_pid_is_dead++; 4742 break; 4743 case EINTR: 4744 goto do_waitpid; 4745 } 4746 else 4747 /* waitpid should always return one of the above values */ 4748 abort (); 4749 while (!command_pid_is_dead) 4750 { 4751 struct timeval timeout; 4752 struct fd_set_wrapper readfds; 4753 char buf[100]; 4754 int i; 4755 4756 /* Use a non-zero timeout to avoid eating up CPU cycles. */ 4757 timeout.tv_sec = 2; 4758 timeout.tv_usec = 0; 4759 readfds = command_fds_to_drain; 4760 switch (select (max_command_fd + 1, &readfds.fds, 4761 (fd_set *)0, (fd_set *)0, 4762 &timeout)) 4763 { 4764 case -1: 4765 if (errno != EINTR) 4766 abort (); 4767 case 0: 4768 /* timeout */ 4769 break; 4770 case 1: 4771 for (i = 0; i <= max_command_fd; i++) 4772 { 4773 if (!FD_ISSET (i, &readfds.fds)) 4774 continue; 4775 /* this fd is non-blocking */ 4776 while (read (i, buf, sizeof (buf)) >= 1) 4777 ; 4778 } 4779 break; 4780 default: 4781 abort (); 4782 } 4783 } 4784 } 4785 #endif 4786 4787 CVS_CHDIR (Tmpdir); 4788 /* Temporarily clear noexec, so that we clean up our temp directory 4789 regardless of it (this could more cleanly be handled by moving 4790 the noexec check to all the unlink_file_dir callers from 4791 unlink_file_dir itself). */ 4792 save_noexec = noexec; 4793 noexec = 0; 4794 /* FIXME? Would be nice to not ignore errors. But what should we do? 4795 We could try to do this before we shut down the network connection, 4796 and try to notify the client (but the client might not be waiting 4797 for responses). We could try something like syslog() or our own 4798 log file. */ 4799 unlink_file_dir (orig_server_temp_dir); 4800 noexec = save_noexec; 4801 4802 if (buf_to_net != NULL) 4803 (void) buf_shutdown (buf_to_net); 4804 } 4805 4806 int server_active = 0; 4807 int server_expanding = 0; 4808 4809 int 4810 server (argc, argv) 4811 int argc; 4812 char **argv; 4813 { 4814 if (argc == -1) 4815 { 4816 static const char *const msg[] = 4817 { 4818 "Usage: %s %s\n", 4819 " Normally invoked by a cvs client on a remote machine.\n", 4820 NULL 4821 }; 4822 usage (msg); 4823 } 4824 /* Ignore argc and argv. They might be from .cvsrc. */ 4825 4826 buf_to_net = fd_buffer_initialize (STDOUT_FILENO, 0, 4827 outbuf_memory_error); 4828 buf_from_net = stdio_buffer_initialize (stdin, 1, outbuf_memory_error); 4829 4830 saved_output = buf_nonio_initialize (outbuf_memory_error); 4831 saved_outerr = buf_nonio_initialize (outbuf_memory_error); 4832 4833 /* Since we're in the server parent process, error should use the 4834 protocol to report error messages. */ 4835 error_use_protocol = 1; 4836 4837 /* OK, now figure out where we stash our temporary files. */ 4838 { 4839 char *p; 4840 4841 /* The code which wants to chdir into server_temp_dir is not set 4842 up to deal with it being a relative path. So give an error 4843 for that case. */ 4844 if (!isabsolute (Tmpdir)) 4845 { 4846 pending_error_text = malloc (80 + strlen (Tmpdir)); 4847 if (pending_error_text == NULL) 4848 { 4849 pending_error = ENOMEM; 4850 } 4851 else 4852 { 4853 sprintf (pending_error_text, 4854 "E Value of %s for TMPDIR is not absolute", Tmpdir); 4855 } 4856 /* FIXME: we would like this error to be persistent, that 4857 is, not cleared by print_pending_error. The current client 4858 will exit as soon as it gets an error, but the protocol spec 4859 does not require a client to do so. */ 4860 } 4861 else 4862 { 4863 int status; 4864 4865 server_temp_dir = malloc (strlen (Tmpdir) + 80); 4866 if (server_temp_dir == NULL) 4867 { 4868 /* 4869 * Strictly speaking, we're not supposed to output anything 4870 * now. But we're about to exit(), give it a try. 4871 */ 4872 printf ("E Fatal server error, aborting.\n\ 4873 error ENOMEM Virtual memory exhausted.\n"); 4874 4875 /* I'm doing this manually rather than via error_exit () 4876 because I'm not sure whether we want to call server_cleanup. 4877 Needs more investigation.... */ 4878 4879 #ifdef SYSTEM_CLEANUP 4880 /* Hook for OS-specific behavior, for example socket 4881 subsystems on NT and OS2 or dealing with windows 4882 and arguments on Mac. */ 4883 SYSTEM_CLEANUP (); 4884 #endif 4885 4886 exit (EXIT_FAILURE); 4887 } 4888 strcpy (server_temp_dir, Tmpdir); 4889 4890 /* Remove a trailing slash from TMPDIR if present. */ 4891 p = server_temp_dir + strlen (server_temp_dir) - 1; 4892 if (*p == '/') 4893 *p = '\0'; 4894 4895 /* 4896 * I wanted to use cvs-serv/PID, but then you have to worry about 4897 * the permissions on the cvs-serv directory being right. So 4898 * use cvs-servPID. 4899 */ 4900 strcat (server_temp_dir, "/cvs-serv"); 4901 4902 p = server_temp_dir + strlen (server_temp_dir); 4903 sprintf (p, "%ld", (long) getpid ()); 4904 4905 orig_server_temp_dir = server_temp_dir; 4906 4907 /* Create the temporary directory, and set the mode to 4908 700, to discourage random people from tampering with 4909 it. */ 4910 status = mkdir_p (server_temp_dir); 4911 if (status != 0 && status != EEXIST) 4912 { 4913 if (alloc_pending (80)) 4914 strcpy (pending_error_text, 4915 "E can't create temporary directory"); 4916 pending_error = status; 4917 } 4918 #ifndef CHMOD_BROKEN 4919 else 4920 { 4921 if (chmod (server_temp_dir, S_IRWXU) < 0) 4922 { 4923 int save_errno = errno; 4924 if (alloc_pending (80)) 4925 strcpy (pending_error_text, "\ 4926 E cannot change permissions on temporary directory"); 4927 pending_error = save_errno; 4928 } 4929 } 4930 #endif 4931 } 4932 } 4933 4934 #ifdef SIGHUP 4935 (void) SIG_register (SIGHUP, server_cleanup); 4936 #endif 4937 #ifdef SIGINT 4938 (void) SIG_register (SIGINT, server_cleanup); 4939 #endif 4940 #ifdef SIGQUIT 4941 (void) SIG_register (SIGQUIT, server_cleanup); 4942 #endif 4943 #ifdef SIGPIPE 4944 (void) SIG_register (SIGPIPE, server_cleanup); 4945 #endif 4946 #ifdef SIGTERM 4947 (void) SIG_register (SIGTERM, server_cleanup); 4948 #endif 4949 4950 /* Now initialize our argument vector (for arguments from the client). */ 4951 4952 /* Small for testing. */ 4953 argument_vector_size = 1; 4954 argument_vector = 4955 (char **) malloc (argument_vector_size * sizeof (char *)); 4956 if (argument_vector == NULL) 4957 { 4958 /* 4959 * Strictly speaking, we're not supposed to output anything 4960 * now. But we're about to exit(), give it a try. 4961 */ 4962 printf ("E Fatal server error, aborting.\n\ 4963 error ENOMEM Virtual memory exhausted.\n"); 4964 4965 /* I'm doing this manually rather than via error_exit () 4966 because I'm not sure whether we want to call server_cleanup. 4967 Needs more investigation.... */ 4968 4969 #ifdef SYSTEM_CLEANUP 4970 /* Hook for OS-specific behavior, for example socket subsystems on 4971 NT and OS2 or dealing with windows and arguments on Mac. */ 4972 SYSTEM_CLEANUP (); 4973 #endif 4974 4975 exit (EXIT_FAILURE); 4976 } 4977 4978 argument_count = 1; 4979 /* This gets printed if the client supports an option which the 4980 server doesn't, causing the server to print a usage message. 4981 FIXME: probably should be using program_name here. 4982 FIXME: just a nit, I suppose, but the usage message the server 4983 prints isn't literally true--it suggests "cvs server" followed 4984 by options which are for a particular command. Might be nice to 4985 say something like "client apparently supports an option not supported 4986 by this server" or something like that instead of usage message. */ 4987 argument_vector[0] = "cvs server"; 4988 4989 while (1) 4990 { 4991 char *cmd, *orig_cmd; 4992 struct request *rq; 4993 int status; 4994 4995 status = buf_read_line (buf_from_net, &cmd, (int *) NULL); 4996 if (status == -2) 4997 { 4998 buf_output0 (buf_to_net, "E Fatal server error, aborting.\n\ 4999 error ENOMEM Virtual memory exhausted.\n"); 5000 break; 5001 } 5002 if (status != 0) 5003 break; 5004 5005 orig_cmd = cmd; 5006 for (rq = requests; rq->name != NULL; ++rq) 5007 if (strncmp (cmd, rq->name, strlen (rq->name)) == 0) 5008 { 5009 int len = strlen (rq->name); 5010 if (cmd[len] == '\0') 5011 cmd += len; 5012 else if (cmd[len] == ' ') 5013 cmd += len + 1; 5014 else 5015 /* 5016 * The first len characters match, but it's a different 5017 * command. e.g. the command is "cooperate" but we matched 5018 * "co". 5019 */ 5020 continue; 5021 5022 if (!(rq->flags & RQ_ROOTLESS) 5023 && CVSroot_directory == NULL) 5024 { 5025 /* For commands which change the way in which data 5026 is sent and received, for example Gzip-stream, 5027 this does the wrong thing. Since the client 5028 assumes that everything is being compressed, 5029 unconditionally, there is no way to give this 5030 error to the client without turning on 5031 compression. The obvious fix would be to make 5032 Gzip-stream RQ_ROOTLESS (with the corresponding 5033 change to the spec), and that might be a good 5034 idea but then again I can see some settings in 5035 CVSROOT about what compression level to allow. 5036 I suppose a more baroque answer would be to 5037 turn on compression (say, at level 1), just 5038 enough to give the "Root request missing" 5039 error. For now we just lose. */ 5040 if (alloc_pending (80)) 5041 sprintf (pending_error_text, 5042 "E Protocol error: Root request missing"); 5043 } 5044 else 5045 (*rq->func) (cmd); 5046 break; 5047 } 5048 if (rq->name == NULL) 5049 { 5050 if (!print_pending_error ()) 5051 { 5052 buf_output0 (buf_to_net, "error unrecognized request `"); 5053 buf_output0 (buf_to_net, cmd); 5054 buf_append_char (buf_to_net, '\''); 5055 buf_append_char (buf_to_net, '\n'); 5056 } 5057 } 5058 free (orig_cmd); 5059 } 5060 server_cleanup (0); 5061 return 0; 5062 } 5063 5064 5065 #if defined (HAVE_KERBEROS) || defined (AUTH_SERVER_SUPPORT) || defined (HAVE_GSSAPI) 5066 static void switch_to_user PROTO((const char *)); 5067 5068 static void 5069 switch_to_user (username) 5070 const char *username; 5071 { 5072 struct passwd *pw; 5073 5074 pw = getpwnam (username); 5075 if (pw == NULL) 5076 { 5077 /* Normally this won't be reached; check_password contains 5078 a similar check. */ 5079 5080 printf ("E Fatal error, aborting.\n\ 5081 error 0 %s: no such user\n", username); 5082 /* Don't worry about server_cleanup; server_active isn't set yet. */ 5083 error_exit (); 5084 } 5085 5086 #if HAVE_INITGROUPS 5087 if (initgroups (pw->pw_name, pw->pw_gid) < 0 5088 # ifdef EPERM 5089 /* At least on the system I tried, initgroups() only works as root. 5090 But we do still want to report ENOMEM and whatever other 5091 errors initgroups() might dish up. */ 5092 && errno != EPERM 5093 # endif 5094 ) 5095 { 5096 /* This could be a warning, but I'm not sure I see the point 5097 in doing that instead of an error given that it would happen 5098 on every connection. We could log it somewhere and not tell 5099 the user. But at least for now make it an error. */ 5100 printf ("error 0 initgroups failed: %s\n", strerror (errno)); 5101 /* Don't worry about server_cleanup; server_active isn't set yet. */ 5102 error_exit (); 5103 } 5104 #endif /* HAVE_INITGROUPS */ 5105 5106 #ifdef SETXID_SUPPORT 5107 /* honor the setgid bit iff set*/ 5108 if (getgid() != getegid()) 5109 { 5110 if (setgid (getegid ()) < 0) 5111 { 5112 /* See comments at setuid call below for more discussion. */ 5113 printf ("error 0 setuid failed: %s\n", strerror (errno)); 5114 /* Don't worry about server_cleanup; 5115 server_active isn't set yet. */ 5116 error_exit (); 5117 } 5118 } 5119 else 5120 #endif 5121 { 5122 if (setgid (pw->pw_gid) < 0) 5123 { 5124 /* See comments at setuid call below for more discussion. */ 5125 printf ("error 0 setuid failed: %s\n", strerror (errno)); 5126 /* Don't worry about server_cleanup; 5127 server_active isn't set yet. */ 5128 error_exit (); 5129 } 5130 } 5131 5132 if (setuid (pw->pw_uid) < 0) 5133 { 5134 /* Note that this means that if run as a non-root user, 5135 CVSROOT/passwd must contain the user we are running as 5136 (e.g. "joe:FsEfVcu:cvs" if run as "cvs" user). This seems 5137 cleaner than ignoring the error like CVS 1.10 and older but 5138 it does mean that some people might need to update their 5139 CVSROOT/passwd file. */ 5140 printf ("error 0 setuid failed: %s\n", strerror (errno)); 5141 /* Don't worry about server_cleanup; server_active isn't set yet. */ 5142 error_exit (); 5143 } 5144 5145 /* We don't want our umask to change file modes. The modes should 5146 be set by the modes used in the repository, and by the umask of 5147 the client. */ 5148 umask (0); 5149 5150 #if HAVE_PUTENV 5151 /* Set LOGNAME and USER in the environment, in case they are 5152 already set to something else. */ 5153 { 5154 char *env; 5155 5156 env = xmalloc (sizeof "LOGNAME=" + strlen (username)); 5157 (void) sprintf (env, "LOGNAME=%s", username); 5158 (void) putenv (env); 5159 5160 env = xmalloc (sizeof "USER=" + strlen (username)); 5161 (void) sprintf (env, "USER=%s", username); 5162 (void) putenv (env); 5163 } 5164 #endif /* HAVE_PUTENV */ 5165 } 5166 #endif 5167 5168 #ifdef AUTH_SERVER_SUPPORT 5169 5170 extern char *crypt PROTO((const char *, const char *)); 5171 5172 5173 /* 5174 * 0 means no entry found for this user. 5175 * 1 means entry found and password matches. 5176 * 2 means entry found, but password does not match. 5177 * 5178 * If success, host_user_ptr will be set to point at the system 5179 * username (i.e., the "real" identity, which may or may not be the 5180 * CVS username) of this user; caller may free this. Global 5181 * CVS_Username will point at an allocated copy of cvs username (i.e., 5182 * the username argument below). 5183 */ 5184 static int 5185 check_repository_password (username, password, repository, host_user_ptr) 5186 char *username, *password, *repository, **host_user_ptr; 5187 { 5188 int retval = 0; 5189 FILE *fp; 5190 char *filename; 5191 char *linebuf = NULL; 5192 size_t linebuf_len; 5193 int found_it = 0; 5194 int namelen; 5195 5196 /* We don't use CVSroot_directory because it hasn't been set yet 5197 * -- our `repository' argument came from the authentication 5198 * protocol, not the regular CVS protocol. 5199 */ 5200 5201 filename = xmalloc (strlen (repository) 5202 + 1 5203 + strlen (CVSROOTADM) 5204 + 1 5205 + strlen (CVSROOTADM_PASSWD) 5206 + 1); 5207 5208 (void) sprintf (filename, "%s/%s/%s", repository, 5209 CVSROOTADM, CVSROOTADM_PASSWD); 5210 5211 fp = CVS_FOPEN (filename, "r"); 5212 if (fp == NULL) 5213 { 5214 if (!existence_error (errno)) 5215 error (0, errno, "cannot open %s", filename); 5216 return 0; 5217 } 5218 5219 /* Look for a relevant line -- one with this user's name. */ 5220 namelen = strlen (username); 5221 while (getline (&linebuf, &linebuf_len, fp) >= 0) 5222 { 5223 if ((strncmp (linebuf, username, namelen) == 0) 5224 && (linebuf[namelen] == ':')) 5225 { 5226 found_it = 1; 5227 break; 5228 } 5229 } 5230 if (ferror (fp)) 5231 error (0, errno, "cannot read %s", filename); 5232 if (fclose (fp) < 0) 5233 error (0, errno, "cannot close %s", filename); 5234 5235 /* If found_it != 0, then linebuf contains the information we need. */ 5236 if (found_it) 5237 { 5238 char *found_password, *host_user_tmp; 5239 5240 strtok (linebuf, ":"); 5241 found_password = strtok (NULL, ": \n"); 5242 host_user_tmp = strtok (NULL, ": \n"); 5243 if (host_user_tmp == NULL) 5244 host_user_tmp = username; 5245 5246 if (strcmp (found_password, crypt (password, found_password)) == 0) 5247 { 5248 /* Give host_user_ptr permanent storage. */ 5249 *host_user_ptr = xstrdup (host_user_tmp); 5250 retval = 1; 5251 } 5252 else 5253 { 5254 *host_user_ptr = NULL; 5255 retval = 2; 5256 } 5257 } 5258 else 5259 { 5260 *host_user_ptr = NULL; 5261 retval = 0; 5262 } 5263 5264 free (filename); 5265 if (linebuf) 5266 free (linebuf); 5267 5268 return retval; 5269 } 5270 5271 5272 /* Return a hosting username if password matches, else NULL. */ 5273 static char * 5274 check_password (username, password, repository) 5275 char *username, *password, *repository; 5276 { 5277 int rc; 5278 char *host_user = NULL; 5279 5280 /* First we see if this user has a password in the CVS-specific 5281 password file. If so, that's enough to authenticate with. If 5282 not, we'll check /etc/passwd. */ 5283 5284 rc = check_repository_password (username, password, repository, 5285 &host_user); 5286 5287 if (rc == 2) 5288 return NULL; 5289 5290 /* else */ 5291 5292 if (rc == 1) 5293 { 5294 /* host_user already set by reference, so just return. */ 5295 goto handle_return; 5296 } 5297 else if (rc == 0 && system_auth) 5298 { 5299 /* No cvs password found, so try /etc/passwd. */ 5300 5301 const char *found_passwd = NULL; 5302 struct passwd *pw; 5303 #ifdef HAVE_GETSPNAM 5304 struct spwd *spw; 5305 5306 spw = getspnam (username); 5307 if (spw != NULL) 5308 { 5309 found_passwd = spw->sp_pwdp; 5310 } 5311 #endif 5312 5313 if (found_passwd == NULL && (pw = getpwnam (username)) != NULL) 5314 { 5315 found_passwd = pw->pw_passwd; 5316 } 5317 5318 if (found_passwd == NULL) 5319 { 5320 printf ("E Fatal error, aborting.\n\ 5321 error 0 %s: no such user\n", username); 5322 5323 /* I'm doing this manually rather than via error_exit () 5324 because I'm not sure whether we want to call server_cleanup. 5325 Needs more investigation.... */ 5326 5327 #ifdef SYSTEM_CLEANUP 5328 /* Hook for OS-specific behavior, for example socket subsystems on 5329 NT and OS2 or dealing with windows and arguments on Mac. */ 5330 SYSTEM_CLEANUP (); 5331 #endif 5332 5333 exit (EXIT_FAILURE); 5334 } 5335 5336 if (*found_passwd) 5337 { 5338 /* user exists and has a password */ 5339 host_user = ((! strcmp (found_passwd, 5340 crypt (password, found_passwd))) 5341 ? username : NULL); 5342 goto handle_return; 5343 } 5344 else if (password && *password) 5345 { 5346 /* user exists and has no system password, but we got 5347 one as parameter */ 5348 host_user = username; 5349 goto handle_return; 5350 } 5351 else 5352 { 5353 /* user exists but has no password at all */ 5354 host_user = NULL; 5355 goto handle_return; 5356 } 5357 } 5358 else if (rc == 0) 5359 { 5360 /* Note that the message _does_ distinguish between the case in 5361 which we check for a system password and the case in which 5362 we do not. It is a real pain to track down why it isn't 5363 letting you in if it won't say why, and I am not convinced 5364 that the potential information disclosure to an attacker 5365 outweighs this. */ 5366 printf ("error 0 no such user %s in CVSROOT/passwd\n", username); 5367 5368 /* I'm doing this manually rather than via error_exit () 5369 because I'm not sure whether we want to call server_cleanup. 5370 Needs more investigation.... */ 5371 5372 #ifdef SYSTEM_CLEANUP 5373 /* Hook for OS-specific behavior, for example socket subsystems on 5374 NT and OS2 or dealing with windows and arguments on Mac. */ 5375 SYSTEM_CLEANUP (); 5376 #endif 5377 exit (EXIT_FAILURE); 5378 } 5379 else 5380 { 5381 /* Something strange happened. We don't know what it was, but 5382 we certainly won't grant authorization. */ 5383 host_user = NULL; 5384 goto handle_return; 5385 } 5386 5387 handle_return: 5388 if (host_user) 5389 { 5390 /* Set CVS_Username here, in allocated space. 5391 It might or might not be the same as host_user. */ 5392 CVS_Username = xmalloc (strlen (username) + 1); 5393 strcpy (CVS_Username, username); 5394 } 5395 5396 return host_user; 5397 } 5398 5399 #endif /* AUTH_SERVER_SUPPORT */ 5400 5401 #if defined (AUTH_SERVER_SUPPORT) || defined (HAVE_GSSAPI) 5402 5403 /* Read username and password from client (i.e., stdin). 5404 If correct, then switch to run as that user and send an ACK to the 5405 client via stdout, else send NACK and die. */ 5406 void 5407 pserver_authenticate_connection () 5408 { 5409 char *tmp = NULL; 5410 size_t tmp_allocated = 0; 5411 #ifdef AUTH_SERVER_SUPPORT 5412 char *repository = NULL; 5413 size_t repository_allocated = 0; 5414 char *username = NULL; 5415 size_t username_allocated = 0; 5416 char *password = NULL; 5417 size_t password_allocated = 0; 5418 5419 char *host_user; 5420 char *descrambled_password; 5421 #endif /* AUTH_SERVER_SUPPORT */ 5422 int verify_and_exit = 0; 5423 5424 /* The Authentication Protocol. Client sends: 5425 * 5426 * BEGIN AUTH REQUEST\n 5427 * <REPOSITORY>\n 5428 * <USERNAME>\n 5429 * <PASSWORD>\n 5430 * END AUTH REQUEST\n 5431 * 5432 * Server uses above information to authenticate, then sends 5433 * 5434 * I LOVE YOU\n 5435 * 5436 * if it grants access, else 5437 * 5438 * I HATE YOU\n 5439 * 5440 * if it denies access (and it exits if denying). 5441 * 5442 * When the client is "cvs login", the user does not desire actual 5443 * repository access, but would like to confirm the password with 5444 * the server. In this case, the start and stop strings are 5445 * 5446 * BEGIN VERIFICATION REQUEST\n 5447 * 5448 * and 5449 * 5450 * END VERIFICATION REQUEST\n 5451 * 5452 * On a verification request, the server's responses are the same 5453 * (with the obvious semantics), but it exits immediately after 5454 * sending the response in both cases. 5455 * 5456 * Why is the repository sent? Well, note that the actual 5457 * client/server protocol can't start up until authentication is 5458 * successful. But in order to perform authentication, the server 5459 * needs to look up the password in the special CVS passwd file, 5460 * before trying /etc/passwd. So the client transmits the 5461 * repository as part of the "authentication protocol". The 5462 * repository will be redundantly retransmitted later, but that's no 5463 * big deal. 5464 */ 5465 5466 #ifdef SO_KEEPALIVE 5467 /* Set SO_KEEPALIVE on the socket, so that we don't hang forever 5468 if the client dies while we are waiting for input. */ 5469 { 5470 int on = 1; 5471 5472 (void) setsockopt (STDIN_FILENO, SOL_SOCKET, SO_KEEPALIVE, 5473 (char *) &on, sizeof on); 5474 } 5475 #endif 5476 5477 /* Make sure the protocol starts off on the right foot... */ 5478 if (getline (&tmp, &tmp_allocated, stdin) < 0) 5479 /* FIXME: what? We could try writing error/eof, but chances 5480 are the network connection is dead bidirectionally. log it 5481 somewhere? */ 5482 ; 5483 5484 if (strcmp (tmp, "BEGIN VERIFICATION REQUEST\n") == 0) 5485 verify_and_exit = 1; 5486 else if (strcmp (tmp, "BEGIN AUTH REQUEST\n") == 0) 5487 ; 5488 else if (strcmp (tmp, "BEGIN GSSAPI REQUEST\n") == 0) 5489 { 5490 #ifdef HAVE_GSSAPI 5491 free (tmp); 5492 gserver_authenticate_connection (); 5493 return; 5494 #else 5495 error (1, 0, "GSSAPI authentication not supported by this server"); 5496 #endif 5497 } 5498 else 5499 error (1, 0, "bad auth protocol start: %s", tmp); 5500 5501 #ifndef AUTH_SERVER_SUPPORT 5502 5503 error (1, 0, "Password authentication not supported by this server"); 5504 5505 #else /* AUTH_SERVER_SUPPORT */ 5506 5507 /* Get the three important pieces of information in order. */ 5508 /* See above comment about error handling. */ 5509 getline (&repository, &repository_allocated, stdin); 5510 getline (&username, &username_allocated, stdin); 5511 getline (&password, &password_allocated, stdin); 5512 5513 /* Make them pure. */ 5514 strip_trailing_newlines (repository); 5515 strip_trailing_newlines (username); 5516 strip_trailing_newlines (password); 5517 5518 /* ... and make sure the protocol ends on the right foot. */ 5519 /* See above comment about error handling. */ 5520 getline (&tmp, &tmp_allocated, stdin); 5521 if (strcmp (tmp, 5522 verify_and_exit ? 5523 "END VERIFICATION REQUEST\n" : "END AUTH REQUEST\n") 5524 != 0) 5525 { 5526 error (1, 0, "bad auth protocol end: %s", tmp); 5527 } 5528 if (!root_allow_ok (repository)) 5529 /* Just give a generic I HATE YOU. This is because CVS 1.9.10 5530 and older clients do not support "error". Once more recent 5531 clients are more widespread, probably want to fix this (it is 5532 a real pain to track down why it isn't letting you in if it 5533 won't say why, and I am not convinced that the potential 5534 information disclosure to an attacker outweighs this). */ 5535 goto i_hate_you; 5536 5537 /* OK, now parse the config file, so we can use it to control how 5538 to check passwords. If there was an error parsing the config 5539 file, parse_config already printed an error. We keep going. 5540 Why? Because if we didn't, then there would be no way to check 5541 in a new CVSROOT/config file to fix the broken one! */ 5542 parse_config (repository); 5543 5544 /* We need the real cleartext before we hash it. */ 5545 descrambled_password = descramble (password); 5546 host_user = check_password (username, descrambled_password, repository); 5547 memset (descrambled_password, 0, strlen (descrambled_password)); 5548 free (descrambled_password); 5549 if (host_user == NULL) 5550 { 5551 i_hate_you: 5552 printf ("I HATE YOU\n"); 5553 fflush (stdout); 5554 5555 /* Don't worry about server_cleanup, server_active isn't set 5556 yet. */ 5557 error_exit (); 5558 } 5559 5560 /* Don't go any farther if we're just responding to "cvs login". */ 5561 if (verify_and_exit) 5562 { 5563 printf ("I LOVE YOU\n"); 5564 fflush (stdout); 5565 5566 #ifdef SYSTEM_CLEANUP 5567 /* Hook for OS-specific behavior, for example socket subsystems on 5568 NT and OS2 or dealing with windows and arguments on Mac. */ 5569 SYSTEM_CLEANUP (); 5570 #endif 5571 5572 exit (0); 5573 } 5574 5575 /* Set Pserver_Repos so that we can check later that the same 5576 repository is sent in later client/server protocol. */ 5577 Pserver_Repos = xmalloc (strlen (repository) + 1); 5578 strcpy (Pserver_Repos, repository); 5579 5580 /* Switch to run as this user. */ 5581 switch_to_user (host_user); 5582 free (tmp); 5583 free (repository); 5584 free (username); 5585 free (password); 5586 5587 printf ("I LOVE YOU\n"); 5588 fflush (stdout); 5589 #endif /* AUTH_SERVER_SUPPORT */ 5590 } 5591 5592 #endif /* AUTH_SERVER_SUPPORT || HAVE_GSSAPI */ 5593 5594 5595 #ifdef HAVE_KERBEROS 5596 void 5597 kserver_authenticate_connection () 5598 { 5599 int status; 5600 char instance[INST_SZ]; 5601 struct sockaddr_in peer; 5602 struct sockaddr_in laddr; 5603 int len; 5604 KTEXT_ST ticket; 5605 AUTH_DAT auth; 5606 char version[KRB_SENDAUTH_VLEN]; 5607 char user[ANAME_SZ]; 5608 5609 strcpy (instance, "*"); 5610 len = sizeof peer; 5611 if (getpeername (STDIN_FILENO, (struct sockaddr *) &peer, &len) < 0 5612 || getsockname (STDIN_FILENO, (struct sockaddr *) &laddr, 5613 &len) < 0) 5614 { 5615 printf ("E Fatal error, aborting.\n\ 5616 error %s getpeername or getsockname failed\n", strerror (errno)); 5617 #ifdef SYSTEM_CLEANUP 5618 /* Hook for OS-specific behavior, for example socket subsystems on 5619 NT and OS2 or dealing with windows and arguments on Mac. */ 5620 SYSTEM_CLEANUP (); 5621 #endif 5622 exit (EXIT_FAILURE); 5623 } 5624 5625 #ifdef SO_KEEPALIVE 5626 /* Set SO_KEEPALIVE on the socket, so that we don't hang forever 5627 if the client dies while we are waiting for input. */ 5628 { 5629 int on = 1; 5630 5631 (void) setsockopt (STDIN_FILENO, SOL_SOCKET, SO_KEEPALIVE, 5632 (char *) &on, sizeof on); 5633 } 5634 #endif 5635 5636 status = krb_recvauth (KOPT_DO_MUTUAL, STDIN_FILENO, &ticket, "rcmd", 5637 instance, &peer, &laddr, &auth, "", sched, 5638 version); 5639 if (status != KSUCCESS) 5640 { 5641 printf ("E Fatal error, aborting.\n\ 5642 error 0 kerberos: %s\n", krb_get_err_text(status)); 5643 #ifdef SYSTEM_CLEANUP 5644 /* Hook for OS-specific behavior, for example socket subsystems on 5645 NT and OS2 or dealing with windows and arguments on Mac. */ 5646 SYSTEM_CLEANUP (); 5647 #endif 5648 exit (EXIT_FAILURE); 5649 } 5650 5651 memcpy (kblock, auth.session, sizeof (C_Block)); 5652 5653 /* Get the local name. */ 5654 status = krb_kntoln (&auth, user); 5655 if (status != KSUCCESS) 5656 { 5657 printf ("E Fatal error, aborting.\n\ 5658 error 0 kerberos: can't get local name: %s\n", krb_get_err_text(status)); 5659 #ifdef SYSTEM_CLEANUP 5660 /* Hook for OS-specific behavior, for example socket subsystems on 5661 NT and OS2 or dealing with windows and arguments on Mac. */ 5662 SYSTEM_CLEANUP (); 5663 #endif 5664 exit (EXIT_FAILURE); 5665 } 5666 5667 /* Switch to run as this user. */ 5668 switch_to_user (user); 5669 } 5670 #endif /* HAVE_KERBEROS */ 5671 5672 #ifdef HAVE_GSSAPI 5673 5674 #ifndef MAXHOSTNAMELEN 5675 #define MAXHOSTNAMELEN (256) 5676 #endif 5677 5678 /* Authenticate a GSSAPI connection. This is called from 5679 pserver_authenticate_connection, and it handles success and failure 5680 the same way. */ 5681 5682 static void 5683 gserver_authenticate_connection () 5684 { 5685 char hostname[MAXHOSTNAMELEN]; 5686 struct hostent *hp; 5687 gss_buffer_desc tok_in, tok_out; 5688 char buf[1024]; 5689 OM_uint32 stat_min, ret; 5690 gss_name_t server_name, client_name; 5691 gss_cred_id_t server_creds; 5692 int nbytes; 5693 gss_OID mechid; 5694 5695 gethostname (hostname, sizeof hostname); 5696 hp = gethostbyname (hostname); 5697 if (hp == NULL) 5698 error (1, 0, "can't get canonical hostname"); 5699 5700 sprintf (buf, "cvs@%s", hp->h_name); 5701 tok_in.value = buf; 5702 tok_in.length = strlen (buf); 5703 5704 if (gss_import_name (&stat_min, &tok_in, GSS_C_NT_HOSTBASED_SERVICE, 5705 &server_name) != GSS_S_COMPLETE) 5706 error (1, 0, "could not import GSSAPI service name %s", buf); 5707 5708 /* Acquire the server credential to verify the client's 5709 authentication. */ 5710 if (gss_acquire_cred (&stat_min, server_name, 0, GSS_C_NULL_OID_SET, 5711 GSS_C_ACCEPT, &server_creds, 5712 NULL, NULL) != GSS_S_COMPLETE) 5713 error (1, 0, "could not acquire GSSAPI server credentials"); 5714 5715 gss_release_name (&stat_min, &server_name); 5716 5717 /* The client will send us a two byte length followed by that many 5718 bytes. */ 5719 if (fread (buf, 1, 2, stdin) != 2) 5720 error (1, errno, "read of length failed"); 5721 5722 nbytes = ((buf[0] & 0xff) << 8) | (buf[1] & 0xff); 5723 assert (nbytes <= sizeof buf); 5724 5725 if (fread (buf, 1, nbytes, stdin) != nbytes) 5726 error (1, errno, "read of data failed"); 5727 5728 gcontext = GSS_C_NO_CONTEXT; 5729 tok_in.length = nbytes; 5730 tok_in.value = buf; 5731 5732 if (gss_accept_sec_context (&stat_min, 5733 &gcontext, /* context_handle */ 5734 server_creds, /* verifier_cred_handle */ 5735 &tok_in, /* input_token */ 5736 NULL, /* channel bindings */ 5737 &client_name, /* src_name */ 5738 &mechid, /* mech_type */ 5739 &tok_out, /* output_token */ 5740 &ret, 5741 NULL, /* ignore time_rec */ 5742 NULL) /* ignore del_cred_handle */ 5743 != GSS_S_COMPLETE) 5744 { 5745 error (1, 0, "could not verify credentials"); 5746 } 5747 5748 /* FIXME: Use Kerberos v5 specific code to authenticate to a user. 5749 We could instead use an authentication to access mapping. */ 5750 { 5751 krb5_context kc; 5752 krb5_principal p; 5753 gss_buffer_desc desc; 5754 5755 krb5_init_context (&kc); 5756 if (gss_display_name (&stat_min, client_name, &desc, 5757 &mechid) != GSS_S_COMPLETE 5758 || krb5_parse_name (kc, ((gss_buffer_t) &desc)->value, &p) != 0 5759 || krb5_aname_to_localname (kc, p, sizeof buf, buf) != 0 5760 || krb5_kuserok (kc, p, buf) != TRUE) 5761 { 5762 error (1, 0, "access denied"); 5763 } 5764 krb5_free_principal (kc, p); 5765 krb5_free_context (kc); 5766 } 5767 5768 if (tok_out.length != 0) 5769 { 5770 char cbuf[2]; 5771 5772 cbuf[0] = (tok_out.length >> 8) & 0xff; 5773 cbuf[1] = tok_out.length & 0xff; 5774 if (fwrite (cbuf, 1, 2, stdout) != 2 5775 || (fwrite (tok_out.value, 1, tok_out.length, stdout) 5776 != tok_out.length)) 5777 error (1, errno, "fwrite failed"); 5778 } 5779 5780 switch_to_user (buf); 5781 5782 printf ("I LOVE YOU\n"); 5783 fflush (stdout); 5784 } 5785 5786 #endif /* HAVE_GSSAPI */ 5787 5788 #endif /* SERVER_SUPPORT */ 5789 5790 #if defined (CLIENT_SUPPORT) || defined (SERVER_SUPPORT) 5791 5792 /* This global variable is non-zero if the user requests encryption on 5793 the command line. */ 5794 int cvsencrypt; 5795 5796 /* This global variable is non-zero if the users requests stream 5797 authentication on the command line. */ 5798 int cvsauthenticate; 5799 5800 #ifdef HAVE_GSSAPI 5801 5802 /* An buffer interface using GSSAPI. This is built on top of a 5803 packetizing buffer. */ 5804 5805 /* This structure is the closure field of the GSSAPI translation 5806 routines. */ 5807 5808 struct cvs_gssapi_wrap_data 5809 { 5810 /* The GSSAPI context. */ 5811 gss_ctx_id_t gcontext; 5812 }; 5813 5814 static int cvs_gssapi_wrap_input PROTO((void *, const char *, char *, int)); 5815 static int cvs_gssapi_wrap_output PROTO((void *, const char *, char *, int, 5816 int *)); 5817 5818 /* Create a GSSAPI wrapping buffer. We use a packetizing buffer with 5819 GSSAPI wrapping routines. */ 5820 5821 struct buffer * 5822 cvs_gssapi_wrap_buffer_initialize (buf, input, gcontext, memory) 5823 struct buffer *buf; 5824 int input; 5825 gss_ctx_id_t gcontext; 5826 void (*memory) PROTO((struct buffer *)); 5827 { 5828 struct cvs_gssapi_wrap_data *gd; 5829 5830 gd = (struct cvs_gssapi_wrap_data *) xmalloc (sizeof *gd); 5831 gd->gcontext = gcontext; 5832 5833 return (packetizing_buffer_initialize 5834 (buf, 5835 input ? cvs_gssapi_wrap_input : NULL, 5836 input ? NULL : cvs_gssapi_wrap_output, 5837 gd, 5838 memory)); 5839 } 5840 5841 /* Unwrap data using GSSAPI. */ 5842 5843 static int 5844 cvs_gssapi_wrap_input (fnclosure, input, output, size) 5845 void *fnclosure; 5846 const char *input; 5847 char *output; 5848 int size; 5849 { 5850 struct cvs_gssapi_wrap_data *gd = 5851 (struct cvs_gssapi_wrap_data *) fnclosure; 5852 gss_buffer_desc inbuf, outbuf; 5853 OM_uint32 stat_min; 5854 int conf; 5855 5856 inbuf.value = (void *) input; 5857 inbuf.length = size; 5858 5859 if (gss_unwrap (&stat_min, gd->gcontext, &inbuf, &outbuf, &conf, NULL) 5860 != GSS_S_COMPLETE) 5861 { 5862 error (1, 0, "gss_unwrap failed"); 5863 } 5864 5865 if (outbuf.length > size) 5866 abort (); 5867 5868 memcpy (output, outbuf.value, outbuf.length); 5869 5870 /* The real packet size is stored in the data, so we don't need to 5871 remember outbuf.length. */ 5872 5873 gss_release_buffer (&stat_min, &outbuf); 5874 5875 return 0; 5876 } 5877 5878 /* Wrap data using GSSAPI. */ 5879 5880 static int 5881 cvs_gssapi_wrap_output (fnclosure, input, output, size, translated) 5882 void *fnclosure; 5883 const char *input; 5884 char *output; 5885 int size; 5886 int *translated; 5887 { 5888 struct cvs_gssapi_wrap_data *gd = 5889 (struct cvs_gssapi_wrap_data *) fnclosure; 5890 gss_buffer_desc inbuf, outbuf; 5891 OM_uint32 stat_min; 5892 int conf_req, conf; 5893 5894 inbuf.value = (void *) input; 5895 inbuf.length = size; 5896 5897 #ifdef ENCRYPTION 5898 conf_req = cvs_gssapi_encrypt; 5899 #else 5900 conf_req = 0; 5901 #endif 5902 5903 if (gss_wrap (&stat_min, gd->gcontext, conf_req, GSS_C_QOP_DEFAULT, 5904 &inbuf, &conf, &outbuf) != GSS_S_COMPLETE) 5905 error (1, 0, "gss_wrap failed"); 5906 5907 /* The packetizing buffer only permits us to add 100 bytes. 5908 FIXME: I don't know what, if anything, is guaranteed by GSSAPI. 5909 This may need to be increased for a different GSSAPI 5910 implementation, or we may need a different algorithm. */ 5911 if (outbuf.length > size + 100) 5912 abort (); 5913 5914 memcpy (output, outbuf.value, outbuf.length); 5915 5916 *translated = outbuf.length; 5917 5918 gss_release_buffer (&stat_min, &outbuf); 5919 5920 return 0; 5921 } 5922 5923 #endif /* HAVE_GSSAPI */ 5924 5925 #ifdef ENCRYPTION 5926 5927 #ifdef HAVE_KERBEROS 5928 5929 /* An encryption interface using Kerberos. This is built on top of a 5930 packetizing buffer. */ 5931 5932 /* This structure is the closure field of the Kerberos translation 5933 routines. */ 5934 5935 struct krb_encrypt_data 5936 { 5937 /* The Kerberos key schedule. */ 5938 Key_schedule sched; 5939 /* The Kerberos DES block. */ 5940 C_Block block; 5941 }; 5942 5943 static int krb_encrypt_input PROTO((void *, const char *, char *, int)); 5944 static int krb_encrypt_output PROTO((void *, const char *, char *, int, 5945 int *)); 5946 5947 /* Create a Kerberos encryption buffer. We use a packetizing buffer 5948 with Kerberos encryption translation routines. */ 5949 5950 struct buffer * 5951 krb_encrypt_buffer_initialize (buf, input, sched, block, memory) 5952 struct buffer *buf; 5953 int input; 5954 Key_schedule sched; 5955 C_Block block; 5956 void (*memory) PROTO((struct buffer *)); 5957 { 5958 struct krb_encrypt_data *kd; 5959 5960 kd = (struct krb_encrypt_data *) xmalloc (sizeof *kd); 5961 memcpy (kd->sched, sched, sizeof (Key_schedule)); 5962 memcpy (kd->block, block, sizeof (C_Block)); 5963 5964 return packetizing_buffer_initialize (buf, 5965 input ? krb_encrypt_input : NULL, 5966 input ? NULL : krb_encrypt_output, 5967 kd, 5968 memory); 5969 } 5970 5971 /* Decrypt Kerberos data. */ 5972 5973 static int 5974 krb_encrypt_input (fnclosure, input, output, size) 5975 void *fnclosure; 5976 const char *input; 5977 char *output; 5978 int size; 5979 { 5980 struct krb_encrypt_data *kd = (struct krb_encrypt_data *) fnclosure; 5981 int tcount; 5982 5983 des_cbc_encrypt ((C_Block *) input, (C_Block *) output, 5984 size, kd->sched, &kd->block, 0); 5985 5986 /* SIZE is the size of the buffer, which is set by the encryption 5987 routine. The packetizing buffer will arrange for the first two 5988 bytes in the decrypted buffer to be the real (unaligned) 5989 length. As a safety check, make sure that the length in the 5990 buffer corresponds to SIZE. Note that the length in the buffer 5991 is just the length of the data. We must add 2 to account for 5992 the buffer count itself. */ 5993 tcount = ((output[0] & 0xff) << 8) + (output[1] & 0xff); 5994 if (((tcount + 2 + 7) & ~7) != size) 5995 error (1, 0, "Decryption failure"); 5996 5997 return 0; 5998 } 5999 6000 /* Encrypt Kerberos data. */ 6001 6002 static int 6003 krb_encrypt_output (fnclosure, input, output, size, translated) 6004 void *fnclosure; 6005 const char *input; 6006 char *output; 6007 int size; 6008 int *translated; 6009 { 6010 struct krb_encrypt_data *kd = (struct krb_encrypt_data *) fnclosure; 6011 int aligned; 6012 6013 /* For security against a known plaintext attack, we should 6014 initialize any padding bytes to random values. Instead, we 6015 just pick up whatever is on the stack, which is at least better 6016 than using zero. */ 6017 6018 /* Align SIZE to an 8 byte boundary. Note that SIZE includes the 6019 two byte buffer count at the start of INPUT which was added by 6020 the packetizing buffer. */ 6021 aligned = (size + 7) & ~7; 6022 6023 /* We use des_cbc_encrypt rather than krb_mk_priv because the 6024 latter sticks a timestamp in the block, and krb_rd_priv expects 6025 that timestamp to be within five minutes of the current time. 6026 Given the way the CVS server buffers up data, that can easily 6027 fail over a long network connection. We trust krb_recvauth to 6028 guard against a replay attack. */ 6029 6030 des_cbc_encrypt ((C_Block *) input, (C_Block *) output, aligned, 6031 kd->sched, &kd->block, 1); 6032 6033 *translated = aligned; 6034 6035 return 0; 6036 } 6037 6038 #endif /* HAVE_KERBEROS */ 6039 #endif /* ENCRYPTION */ 6040 #endif /* defined (CLIENT_SUPPORT) || defined (SERVER_SUPPORT) */ 6041 6042 /* Output LEN bytes at STR. If LEN is zero, then output up to (not including) 6043 the first '\0' byte. */ 6044 6045 void 6046 cvs_output (str, len) 6047 const char *str; 6048 size_t len; 6049 { 6050 if (len == 0) 6051 len = strlen (str); 6052 #ifdef SERVER_SUPPORT 6053 if (error_use_protocol) 6054 { 6055 buf_output (saved_output, str, len); 6056 buf_copy_lines (buf_to_net, saved_output, 'M'); 6057 } 6058 else if (server_active) 6059 { 6060 buf_output (saved_output, str, len); 6061 buf_copy_lines (protocol, saved_output, 'M'); 6062 buf_send_counted (protocol); 6063 } 6064 else 6065 #endif 6066 { 6067 size_t written; 6068 size_t to_write = len; 6069 const char *p = str; 6070 6071 /* For symmetry with cvs_outerr we would call fflush (stderr) 6072 here. I guess the assumption is that stderr will be 6073 unbuffered, so we don't need to. That sounds like a sound 6074 assumption from the manpage I looked at, but if there was 6075 something fishy about it, my guess is that calling fflush 6076 would not produce a significant performance problem. */ 6077 6078 while (to_write > 0) 6079 { 6080 written = fwrite (p, 1, to_write, stdout); 6081 if (written == 0) 6082 break; 6083 p += written; 6084 to_write -= written; 6085 } 6086 } 6087 } 6088 6089 /* Output LEN bytes at STR in binary mode. If LEN is zero, then 6090 output zero bytes. */ 6091 6092 void 6093 cvs_output_binary (str, len) 6094 char *str; 6095 size_t len; 6096 { 6097 #ifdef SERVER_SUPPORT 6098 if (error_use_protocol || server_active) 6099 { 6100 struct buffer *buf; 6101 char size_text[40]; 6102 6103 if (error_use_protocol) 6104 buf = buf_to_net; 6105 else 6106 buf = protocol; 6107 6108 if (!supported_response ("Mbinary")) 6109 { 6110 error (0, 0, "\ 6111 this client does not support writing binary files to stdout"); 6112 return; 6113 } 6114 6115 buf_output0 (buf, "Mbinary\012"); 6116 sprintf (size_text, "%lu\012", (unsigned long) len); 6117 buf_output0 (buf, size_text); 6118 6119 /* Not sure what would be involved in using buf_append_data here 6120 without stepping on the toes of our caller (which is responsible 6121 for the memory allocation of STR). */ 6122 buf_output (buf, str, len); 6123 6124 if (!error_use_protocol) 6125 buf_send_counted (protocol); 6126 } 6127 else 6128 #endif 6129 { 6130 size_t written; 6131 size_t to_write = len; 6132 const char *p = str; 6133 6134 /* For symmetry with cvs_outerr we would call fflush (stderr) 6135 here. I guess the assumption is that stderr will be 6136 unbuffered, so we don't need to. That sounds like a sound 6137 assumption from the manpage I looked at, but if there was 6138 something fishy about it, my guess is that calling fflush 6139 would not produce a significant performance problem. */ 6140 #ifdef USE_SETMODE_STDOUT 6141 int oldmode; 6142 6143 /* It is possible that this should be the same ifdef as 6144 USE_SETMODE_BINARY but at least for the moment we keep them 6145 separate. Mostly this is just laziness and/or a question 6146 of what has been tested where. Also there might be an 6147 issue of setmode vs. _setmode. */ 6148 /* The Windows doc says to call setmode only right after startup. 6149 I assume that what they are talking about can also be helped 6150 by flushing the stream before changing the mode. */ 6151 fflush (stdout); 6152 oldmode = _setmode (_fileno (stdout), OPEN_BINARY); 6153 if (oldmode < 0) 6154 error (0, errno, "failed to setmode on stdout"); 6155 #endif 6156 6157 while (to_write > 0) 6158 { 6159 written = fwrite (p, 1, to_write, stdout); 6160 if (written == 0) 6161 break; 6162 p += written; 6163 to_write -= written; 6164 } 6165 #ifdef USE_SETMODE_STDOUT 6166 fflush (stdout); 6167 if (_setmode (_fileno (stdout), oldmode) != OPEN_BINARY) 6168 error (0, errno, "failed to setmode on stdout"); 6169 #endif 6170 } 6171 } 6172 6173 /* Like CVS_OUTPUT but output is for stderr not stdout. */ 6174 6175 void 6176 cvs_outerr (str, len) 6177 const char *str; 6178 size_t len; 6179 { 6180 if (len == 0) 6181 len = strlen (str); 6182 #ifdef SERVER_SUPPORT 6183 if (error_use_protocol) 6184 { 6185 buf_output (saved_outerr, str, len); 6186 buf_copy_lines (buf_to_net, saved_outerr, 'E'); 6187 } 6188 else if (server_active) 6189 { 6190 buf_output (saved_outerr, str, len); 6191 buf_copy_lines (protocol, saved_outerr, 'E'); 6192 buf_send_counted (protocol); 6193 } 6194 else 6195 #endif 6196 { 6197 size_t written; 6198 size_t to_write = len; 6199 const char *p = str; 6200 6201 /* Make sure that output appears in order if stdout and stderr 6202 point to the same place. For the server case this is taken 6203 care of by the fact that saved_outerr always holds less 6204 than a line. */ 6205 fflush (stdout); 6206 6207 while (to_write > 0) 6208 { 6209 written = fwrite (p, 1, to_write, stderr); 6210 if (written == 0) 6211 break; 6212 p += written; 6213 to_write -= written; 6214 } 6215 } 6216 } 6217 6218 /* Flush stderr. stderr is normally flushed automatically, of course, 6219 but this function is used to flush information from the server back 6220 to the client. */ 6221 6222 void 6223 cvs_flusherr () 6224 { 6225 #ifdef SERVER_SUPPORT 6226 if (error_use_protocol) 6227 { 6228 /* Flush what we can to the network, but don't block. */ 6229 buf_flush (buf_to_net, 0); 6230 } 6231 else if (server_active) 6232 { 6233 /* Send a special count to tell the parent to flush. */ 6234 buf_send_special_count (protocol, -1); 6235 } 6236 else 6237 #endif 6238 fflush (stderr); 6239 } 6240 6241 /* Make it possible for the user to see what has been written to 6242 stdout (it is up to the implementation to decide exactly how far it 6243 should go to ensure this). */ 6244 6245 void 6246 cvs_flushout () 6247 { 6248 #ifdef SERVER_SUPPORT 6249 if (error_use_protocol) 6250 { 6251 /* Flush what we can to the network, but don't block. */ 6252 buf_flush (buf_to_net, 0); 6253 } 6254 else if (server_active) 6255 { 6256 /* Just do nothing. This is because the code which 6257 cvs_flushout replaces, setting stdout to line buffering in 6258 main.c, didn't get called in the server child process. But 6259 in the future it is quite plausible that we'll want to make 6260 this case work analogously to cvs_flusherr. */ 6261 } 6262 else 6263 #endif 6264 fflush (stdout); 6265 } 6266 6267 /* Output TEXT, tagging it according to TAG. There are lots more 6268 details about what TAG means in cvsclient.texi but for the simple 6269 case (e.g. non-client/server), TAG is just "newline" to output a 6270 newline (in which case TEXT must be NULL), and any other tag to 6271 output normal text. 6272 6273 Note that there is no way to output either \0 or \n as part of TEXT. */ 6274 6275 void 6276 cvs_output_tagged (tag, text) 6277 char *tag; 6278 char *text; 6279 { 6280 if (text != NULL && strchr (text, '\n') != NULL) 6281 /* Uh oh. The protocol has no way to cope with this. For now 6282 we dump core, although that really isn't such a nice 6283 response given that this probably can be caused by newlines 6284 in filenames and other causes other than bugs in CVS. Note 6285 that we don't want to turn this into "MT newline" because 6286 this case is a newline within a tagged item, not a newline 6287 as extraneous sugar for the user. */ 6288 assert (0); 6289 6290 /* Start and end tags don't take any text, per cvsclient.texi. */ 6291 if (tag[0] == '+' || tag[0] == '-') 6292 assert (text == NULL); 6293 6294 #ifdef SERVER_SUPPORT 6295 if (server_active && supported_response ("MT")) 6296 { 6297 struct buffer *buf; 6298 6299 if (error_use_protocol) 6300 buf = buf_to_net; 6301 else 6302 buf = protocol; 6303 6304 buf_output0 (buf, "MT "); 6305 buf_output0 (buf, tag); 6306 if (text != NULL) 6307 { 6308 buf_output (buf, " ", 1); 6309 buf_output0 (buf, text); 6310 } 6311 buf_output (buf, "\n", 1); 6312 6313 if (!error_use_protocol) 6314 buf_send_counted (protocol); 6315 } 6316 else 6317 #endif 6318 { 6319 if (strcmp (tag, "newline") == 0) 6320 cvs_output ("\n", 1); 6321 else if (text != NULL) 6322 cvs_output (text, 0); 6323 } 6324 } 6325