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