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