1 /* CVS client-related stuff.
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details. */
15 #endif /* HAVE_CONFIG_H */
21 #include "log-buffer.h"
28 #include "socket-client.h"
29 #include "rsh-client.h"
32 # include "gssapi-client.h"
36 # include "kerberos4-client.h"
41 /* Keep track of any paths we are sending for Max-dotdot so that we can verify
42 * that uplevel paths coming back form the server are valid.
44 * FIXME: The correct way to do this is probably provide some sort of virtual
45 * path map on the client side. This would be generic enough to be applied to
46 * absolute paths supplied by the user too.
48 static List *uppaths = NULL;
52 static void add_prune_candidate (const char *);
54 /* All the commands. */
55 int add (int argc, char **argv);
56 int admin (int argc, char **argv);
57 int checkout (int argc, char **argv);
58 int commit (int argc, char **argv);
59 int diff (int argc, char **argv);
60 int history (int argc, char **argv);
61 int import (int argc, char **argv);
62 int cvslog (int argc, char **argv);
63 int patch (int argc, char **argv);
64 int release (int argc, char **argv);
65 int cvsremove (int argc, char **argv);
66 int rtag (int argc, char **argv);
67 int status (int argc, char **argv);
68 int tag (int argc, char **argv);
69 int update (int argc, char **argv);
71 /* All the response handling functions. */
72 static void handle_ok (char *, int);
73 static void handle_error (char *, int);
74 static void handle_valid_requests (char *, int);
75 static void handle_checked_in (char *, int);
76 static void handle_new_entry (char *, int);
77 static void handle_checksum (char *, int);
78 static void handle_copy_file (char *, int);
79 static void handle_updated (char *, int);
80 static void handle_merged (char *, int);
81 static void handle_patched (char *, int);
82 static void handle_rcs_diff (char *, int);
83 static void handle_removed (char *, int);
84 static void handle_remove_entry (char *, int);
85 static void handle_set_static_directory (char *, int);
86 static void handle_clear_static_directory (char *, int);
87 static void handle_set_sticky (char *, int);
88 static void handle_clear_sticky (char *, int);
89 static void handle_clear_template (char *, int);
90 static void handle_module_expansion (char *, int);
91 static void handle_wrapper_rcs_option (char *, int);
92 static void handle_m (char *, int);
93 static void handle_e (char *, int);
94 static void handle_f (char *, int);
95 static void handle_notified (char *, int);
97 static size_t try_read_from_server (char *, size_t);
99 static void auth_server (cvsroot_t *, struct buffer *, struct buffer *,
100 int, int, struct hostent *);
102 /* We need to keep track of the list of directories we've sent to the
103 server. This list, along with the current CVSROOT, will help us
104 decide which command-line arguments to send. */
105 List *dirs_sent_to_server = NULL;
107 static int is_arg_a_parent_or_listed_dir (Node *, void *);
110 is_arg_a_parent_or_listed_dir( Node *n, void *d )
112 char *directory = n->key; /* name of the dir sent to server */
113 char *this_argv_elem = (char *) d; /* this argv element */
115 /* Say we should send this argument if the argument matches the
116 beginning of a directory name sent to the server. This way,
117 the server will know to start at the top of that directory
118 hierarchy and descend. */
120 if (strncmp (directory, this_argv_elem, strlen (this_argv_elem)) == 0)
126 static int arg_should_not_be_sent_to_server (char *);
128 /* Return nonzero if this argument should not be sent to the
132 arg_should_not_be_sent_to_server( char *arg )
134 /* Decide if we should send this directory name to the server. We
135 should always send argv[i] if:
137 1) the list of directories sent to the server is empty (as it
138 will be for checkout, etc.).
140 2) the argument is "."
142 3) the argument is a file in the cwd and the cwd is checked out
143 from the current root
145 4) the argument lies within one of the paths in
150 if (list_isempty (dirs_sent_to_server))
151 return 0; /* always send it */
153 if (strcmp (arg, ".") == 0)
154 return 0; /* always send it */
156 /* We should send arg if it is one of the directories sent to the
157 server or the parent of one; this tells the server to descend
158 the hierarchy starting at this level. */
161 if (walklist (dirs_sent_to_server, is_arg_a_parent_or_listed_dir, arg))
164 /* If arg wasn't a parent, we don't know anything about it (we
165 would have seen something related to it during the
166 send_files phase). Don't send it. */
170 /* Try to decide whether we should send arg to the server by
171 checking the contents of the corresponding CVSADM directory. */
175 /* Calculate "dirname arg" */
176 for (t = arg + strlen (arg) - 1; t >= arg; t--)
182 /* Now we're either poiting to the beginning of the
183 string, or we found a path separator. */
186 /* Found a path separator. */
190 /* First, check to see if we sent this directory to the
191 server, because it takes less time than actually
192 opening the stuff in the CVSADM directory. */
193 if (walklist (dirs_sent_to_server, is_arg_a_parent_or_listed_dir,
196 *t = c; /* make sure to un-truncate the arg */
200 /* Since we didn't find it in the list, check the CVSADM
202 this_root = Name_Root (arg, (char *) NULL);
207 /* We're at the beginning of the string. Look at the
208 CVSADM files in cwd. */
209 this_root = (CVSroot_cmdline ? xstrdup(CVSroot_cmdline)
210 : Name_Root ((char *) NULL, (char *) NULL));
213 /* Now check the value for root. */
214 if (this_root && current_parsed_root
215 && (strcmp (this_root, current_parsed_root->original) != 0))
217 /* Don't send this, since the CVSROOTs don't match. */
224 /* OK, let's send it. */
230 #endif /* CLIENT_SUPPORT */
234 #if defined(CLIENT_SUPPORT) || defined(SERVER_SUPPORT)
236 /* Shared with server. */
239 * Return a malloc'd, '\0'-terminated string
240 * corresponding to the mode in SB.
243 mode_to_string (mode_t mode)
245 char buf[18], u[4], g[4], o[4];
249 if (mode & S_IRUSR) u[i++] = 'r';
250 if (mode & S_IWUSR) u[i++] = 'w';
251 if (mode & S_IXUSR) u[i++] = 'x';
255 if (mode & S_IRGRP) g[i++] = 'r';
256 if (mode & S_IWGRP) g[i++] = 'w';
257 if (mode & S_IXGRP) g[i++] = 'x';
261 if (mode & S_IROTH) o[i++] = 'r';
262 if (mode & S_IWOTH) o[i++] = 'w';
263 if (mode & S_IXOTH) o[i++] = 'x';
266 sprintf(buf, "u=%s,g=%s,o=%s", u, g, o);
271 * Change mode of FILENAME to MODE_STRING.
272 * Returns 0 for success or errno code.
273 * If RESPECT_UMASK is set, then honor the umask.
276 change_mode( char *filename, char *mode_string, int respect_umask )
282 /* We can only distinguish between
285 3) Picasso's "Blue Period"
286 We handle the first two. */
290 if ((p[0] == 'u' || p[0] == 'g' || p[0] == 'o') && p[1] == '=')
293 while (*q != ',' && *q != '\0')
300 /* Skip to the next field. */
301 while (*p != ',' && *p != '\0')
307 /* xchmod honors the umask for us. In the !respect_umask case, we
308 don't try to cope with it (probably to handle that well, the server
309 needs to deal with modes in data structures, rather than via the
310 modes in temporary files). */
311 xchmod (filename, writeable);
314 #else /* ! CHMOD_BROKEN */
323 if ((p[0] == 'u' || p[0] == 'g' || p[0] == 'o') && p[1] == '=')
325 int can_read = 0, can_write = 0, can_execute = 0;
327 while (*q != ',' && *q != '\0')
346 else if (p[0] == 'g')
355 else if (p[0] == 'o')
365 /* Skip to the next field. */
366 while (*p != ',' && *p != '\0')
375 (void) umask (oumask);
379 if (chmod (filename, mode) < 0)
382 #endif /* ! CHMOD_BROKEN */
385 #endif /* CLIENT_SUPPORT or SERVER_SUPPORT */
387 #ifdef CLIENT_SUPPORT
389 int client_prune_dirs;
391 static List *ignlist = (List *) NULL;
393 /* Buffer to write to the server. */
394 static struct buffer *global_to_server;
396 /* Buffer used to read from the server. */
397 static struct buffer *global_from_server;
402 * Read a line from the server. Result does not include the terminating \n.
404 * Space for the result is malloc'd and should be freed by the caller.
406 * Returns number of bytes read.
409 read_line_via (struct buffer *via_from_buffer, struct buffer *via_to_buffer,
416 status = buf_flush (via_to_buffer, 1);
418 error (1, status, "writing to server");
420 status = buf_read_line (via_from_buffer, &result, &len);
425 "end of file from server (consult above messages if any)");
426 else if (status == -2)
427 error (1, 0, "out of memory");
429 error (1, status, "reading from server");
443 read_line (char **resultp)
445 return read_line_via (global_from_server, global_to_server, resultp);
449 #endif /* CLIENT_SUPPORT */
452 #if defined(CLIENT_SUPPORT) || defined(SERVER_SUPPORT)
455 * Zero if compression isn't supported or requested; non-zero to indicate
456 * a compression level to request from gzip.
461 * Level of compression to use when running gzip on a single file.
465 #endif /* CLIENT_SUPPORT or SERVER_SUPPORT */
467 #ifdef CLIENT_SUPPORT
470 * The Repository for the top level of this command (not necessarily
471 * the CVSROOT, just the current directory at the time we do it).
473 static char *toplevel_repos = NULL;
475 /* Working directory when we first started. Note: we could speed things
476 up on some systems by using savecwd.h here instead of just always
481 handle_ok( char *args, int len )
487 handle_error( char *args, int len )
489 int something_printed;
492 * First there is a symbolic error code followed by a space, which
495 char *p = strchr (args, ' ');
498 error (0, 0, "invalid data from cvs server");
503 /* Next we print the text of the message from the server. We
504 probably should be prefixing it with "server error" or some
505 such, because if it is something like "Out of memory", the
506 current behavior doesn't say which machine is out of
510 something_printed = 0;
511 for (; len > 0; --len)
513 something_printed = 1;
516 if (something_printed)
521 handle_valid_requests( char *args, int len )
531 for (rq = requests; rq->name != NULL; ++rq)
533 if (strcmp (rq->name, p) == 0)
536 if (rq->name == NULL)
538 * It is a request we have never heard of (and thus never
539 * will want to use). So don't worry about it.
544 if (rq->flags & RQ_ENABLEME)
547 * Server wants to know if we have this, to enable the
550 send_to_server (rq->name, 0);
551 send_to_server ("\012", 0);
554 rq->flags |= RQ_SUPPORTED;
558 for (rq = requests; rq->name != NULL; ++rq)
560 if ((rq->flags & RQ_SUPPORTED)
561 || (rq->flags & RQ_ENABLEME))
563 if (rq->flags & RQ_ESSENTIAL)
564 error (1, 0, "request `%s' not supported by server", rq->name);
571 * This is a proc for walklist(). It inverts the error return premise of
575 * True If this path is prefixed by one of the paths in walklist and
576 * does not step above the prefix path.
580 int path_list_prefixed (Node *p, void *closure)
582 const char *questionable = closure;
583 const char *prefix = p->key;
584 if (strncmp (prefix, questionable, strlen (prefix))) return 0;
585 questionable += strlen (prefix);
586 while (ISSLASH (*questionable)) questionable++;
587 if (*questionable == '\0') return 1;
588 return pathname_levels (questionable);
594 * Need to validate the client pathname. Disallowed paths include:
597 * 2. Pathnames that do not reference a specifically requested update
600 * In case 2, we actually only check that the directory is under the uppermost
601 * directories mentioned on the command line.
604 * True If the path is valid.
608 int is_valid_client_path (const char *pathname)
610 /* 1. Absolute paths. */
611 if (isabsolute (pathname)) return 0;
612 /* 2. No up-references in path. */
613 if (pathname_levels (pathname) == 0) return 1;
614 /* 2. No Max-dotdot paths registered. */
615 if (uppaths == NULL) return 0;
617 return walklist (uppaths, path_list_prefixed, (void *)pathname);
623 * Do all the processing for PATHNAME, where pathname consists of the
624 * repository and the filename. The parameters we pass to FUNC are:
625 * DATA is just the DATA parameter which was passed to
626 * call_in_directory; ENT_LIST is a pointer to an entries list (which
627 * we manage the storage for); SHORT_PATHNAME is the pathname of the
628 * file relative to the (overall) directory in which the command is
629 * taking place; and FILENAME is the filename portion only of
630 * SHORT_PATHNAME. When we call FUNC, the curent directory points to
631 * the directory portion of SHORT_PATHNAME. */
634 call_in_directory( char *pathname,
635 void (*func) ( char *_data, List *_ent_list,
636 char *_short_pathname, char *_filename ),
639 /* This variable holds the result of Entries_Open. */
640 List *last_entries = NULL;
643 /* This is what we get when we hook up the directory (working directory
644 name) from PATHNAME with the filename from REPOSNAME. For example:
646 reposname: /u/src/master/ccvs/foo/ChangeLog
647 short_pathname: ccvs/src/ChangeLog
649 char *short_pathname;
653 * Do the whole descent in parallel for the repositories, so we
654 * know what to put in CVS/Repository files. I'm not sure the
655 * full hair is necessary since the server does a similar
656 * computation; I suspect that we only end up creating one
657 * directory at a time anyway.
659 * Also note that we must *only* worry about this stuff when we
660 * are creating directories; `cvs co foo/bar; cd foo/bar; cvs co
661 * CVSROOT; cvs update' is legitimate, but in this case
662 * foo/bar/CVSROOT/CVS/Repository is not a subdirectory of
663 * foo/bar/CVS/Repository.
669 int reposdirname_absolute;
673 read_line (&reposname);
674 assert (reposname != NULL);
676 reposdirname_absolute = 0;
677 if (strncmp (reposname, toplevel_repos, strlen (toplevel_repos)) != 0)
679 reposdirname_absolute = 1;
680 short_repos = reposname;
684 short_repos = reposname + strlen (toplevel_repos) + 1;
685 if (short_repos[-1] != '/')
687 reposdirname_absolute = 1;
688 short_repos = reposname;
692 /* Now that we have SHORT_REPOS, we can calculate the path to the file we
693 * are being requested to operate on.
695 filename = strrchr (short_repos, '/');
696 if (filename == NULL)
697 filename = short_repos;
701 short_pathname = xmalloc (strlen (pathname) + strlen (filename) + 5);
702 strcpy (short_pathname, pathname);
703 strcat (short_pathname, filename);
705 /* Now that we know the path to the file we were requested to operate on,
706 * we can verify that it is valid.
708 * For security reasons, if SHORT_PATHNAME is absolute or attempts to
709 * ascend outside of the current sanbbox, we abort. The server should not
710 * send us anything but relative paths which remain inside the sandbox
711 * here. Anything less means a trojan CVS server could create and edit
712 * arbitrary files on the client.
714 if (!is_valid_client_path (short_pathname))
717 "Server attempted to update a file via an invalid pathname:");
718 error (1, 0, "`%s'.", short_pathname);
721 reposdirname = xstrdup (short_repos);
722 p = strrchr (reposdirname, '/');
725 reposdirname = xrealloc (reposdirname, 2);
726 reposdirname[0] = '.'; reposdirname[1] = '\0';
731 dir_name = xstrdup (pathname);
732 p = strrchr (dir_name, '/');
735 dir_name = xrealloc (dir_name, 2);
736 dir_name[0] = '.'; dir_name[1] = '\0';
740 if (client_prune_dirs)
741 add_prune_candidate (dir_name);
743 if (toplevel_wd == NULL)
745 toplevel_wd = xgetwd ();
746 if (toplevel_wd == NULL)
747 error (1, errno, "could not get working directory");
750 if (CVS_CHDIR (toplevel_wd) < 0)
751 error (1, errno, "could not chdir to %s", toplevel_wd);
753 /* Create the CVS directory at the top level if needed. The
754 isdir seems like an unneeded system call, but it *does*
755 need to be called both if the CVS_CHDIR below succeeds
756 (e.g. "cvs co .") or if it fails (e.g. basicb-1a in
757 testsuite). We only need to do this for the "." case,
758 since the server takes care of forcing this directory to be
759 created in all other cases. If we don't create CVSADM
760 here, the call to Entries_Open below will fail. FIXME:
761 perhaps this means that we should change our algorithm
762 below that calls Create_Admin instead of having this code
764 if (/* I think the reposdirname_absolute case has to do with
765 things like "cvs update /foo/bar". In any event, the
766 code below which tries to put toplevel_repos into
767 CVS/Repository is almost surely unsuited to
768 the reposdirname_absolute case. */
769 !reposdirname_absolute
770 && (strcmp (dir_name, ".") == 0)
778 repo = xmalloc (strlen (toplevel_repos)
780 strcpy (repo, toplevel_repos);
781 r = repo + strlen (repo);
782 if (r[-1] != '.' || r[-2] != '/')
785 Create_Admin (".", ".", repo, (char *) NULL,
786 (char *) NULL, 0, 1, 1);
791 if (CVS_CHDIR (dir_name) < 0)
796 if (! existence_error (errno))
797 error (1, errno, "could not chdir to %s", dir_name);
799 /* Directory does not exist, we need to create it. */
802 /* Provided we are willing to assume that directories get
803 created one at a time, we could simplify this a lot.
804 Do note that one aspect still would need to walk the
805 dir_name path: the checking for "fncmp (dir, CVSADM)". */
807 dir = xmalloc (strlen (dir_name) + 1);
809 rdirp = reposdirname;
811 /* This algorithm makes nested directories one at a time
812 and create CVS administration files in them. For
813 example, we're checking out foo/bar/baz from the
816 1) create foo, point CVS/Repository to <root>/foo
817 2) .. foo/bar .. <root>/foo/bar
818 3) .. foo/bar/baz .. <root>/foo/bar/baz
820 As you can see, we're just stepping along DIR_NAME (with
821 DIRP) and REPOSDIRNAME (with RDIRP) respectively.
823 We need to be careful when we are checking out a
824 module, however, since DIR_NAME and REPOSDIRNAME are not
825 going to be the same. Since modules will not have any
826 slashes in their names, we should watch the output of
827 STRCHR to decide whether or not we should use STRCHR on
828 the RDIRP. That is, if we're down to a module name,
829 don't keep picking apart the repository directory name. */
833 dirp = strchr (dirp, '/');
836 strncpy (dir, dir_name, dirp - dir_name);
837 dir[dirp - dir_name] = '\0';
838 /* Skip the slash. */
841 /* This just means that the repository string has
842 fewer components than the dir_name string. But
843 that is OK (e.g. see modules3-8 in testsuite). */
846 rdirp = strchr (rdirp, '/');
850 /* If there are no more slashes in the dir name,
851 we're down to the most nested directory -OR- to
852 the name of a module. In the first case, we
853 should be down to a DIRP that has no slashes,
854 so it won't help/hurt to do another STRCHR call
855 on DIRP. It will definitely hurt, however, if
856 we're down to a module name, since a module
857 name can point to a nested directory (that is,
858 DIRP will still have slashes in it. Therefore,
859 we should set it to NULL so the routine below
860 copies the contents of REMOTEDIRNAME onto the
861 root repository directory (does this if rdirp
862 is set to NULL, because we used to do an extra
863 STRCHR call here). */
866 strcpy (dir, dir_name);
869 if (fncmp (dir, CVSADM) == 0)
871 error (0, 0, "cannot create a directory named %s", dir);
872 error (0, 0, "because CVS uses \"%s\" for its own uses",
874 error (1, 0, "rename the directory and try again");
877 if (mkdir_if_needed (dir))
879 /* It already existed, fine. Just keep going. */
881 else if (strcmp (cvs_cmd_name, "export") == 0)
882 /* Don't create CVSADM directories if this is export. */
887 * Put repository in CVS/Repository. For historical
888 * (pre-CVS/Root) reasons, this is an absolute pathname,
889 * but what really matters is the part of it which is
890 * relative to cvsroot.
895 repo = xmalloc (strlen (reposdirname)
896 + strlen (toplevel_repos)
898 if (reposdirname_absolute)
902 strcpy (repo, toplevel_repos);
904 r = repo + strlen (repo);
909 /* See comment near start of function; the only
910 way that the server can put the right thing
911 in each CVS/Repository file is to create the
912 directories one at a time. I think that the
913 CVS server has been doing this all along. */
915 warning: server is not creating directories one at a time");
916 strncpy (r, reposdirname, rdirp - reposdirname);
917 r[rdirp - reposdirname] = '\0';
920 strcpy (r, reposdirname);
922 Create_Admin (dir, dir, repo,
923 (char *)NULL, (char *)NULL, 0, 0, 1);
926 b = strrchr (dir, '/');
928 Subdir_Register ((List *) NULL, (char *) NULL, dir);
932 Subdir_Register ((List *) NULL, dir, b + 1);
939 /* Skip the slash. */
943 } while (dirp != NULL);
945 /* Now it better work. */
946 if ( CVS_CHDIR (dir_name) < 0)
947 error (1, errno, "could not chdir to %s", dir_name);
949 else if (strcmp (cvs_cmd_name, "export") == 0)
950 /* Don't create CVSADM directories if this is export. */
952 else if (!isdir (CVSADM))
955 * Put repository in CVS/Repository. For historical
956 * (pre-CVS/Root) reasons, this is an absolute pathname,
957 * but what really matters is the part of it which is
958 * relative to cvsroot.
962 if (reposdirname_absolute)
966 repo = xmalloc (strlen (reposdirname)
967 + strlen (toplevel_repos)
969 strcpy (repo, toplevel_repos);
971 strcat (repo, reposdirname);
974 Create_Admin (".", ".", repo, (char *)NULL, (char *)NULL, 0, 1, 1);
975 if (repo != reposdirname)
979 if (strcmp (cvs_cmd_name, "export") != 0)
981 last_entries = Entries_Open (0, dir_name);
983 /* If this is a newly created directory, we will record
984 all subdirectory information, so call Subdirs_Known in
985 case there are no subdirectories. If this is not a
986 newly created directory, it may be an old working
987 directory from before we recorded subdirectory
988 information in the Entries file. We force a search for
989 all subdirectories now, to make sure our subdirectory
990 information is up to date. If the Entries file does
991 record subdirectory information, then this call only
992 does list manipulation. */
994 Subdirs_Known (last_entries);
999 dirlist = Find_Directories ((char *) NULL, W_LOCAL,
1004 free (reposdirname);
1005 (*func) (data, last_entries, short_pathname, filename);
1006 if (last_entries != NULL)
1007 Entries_Close (last_entries);
1009 free (short_pathname);
1014 copy_a_file( char *data, List *ent_list, char *short_pathname, char *filename )
1017 #ifdef USE_VMS_FILENAMES
1021 read_line (&newname);
1023 #ifdef USE_VMS_FILENAMES
1024 /* Mogrify the filename so VMS is happy with it. */
1025 for(p = newname; *p; p++)
1026 if(*p == '.' || *p == '#') *p = '_';
1028 /* cvsclient.texi has said for a long time that newname must be in the
1029 same directory. Wouldn't want a malicious or buggy server overwriting
1030 ~/.profile, /etc/passwd, or anything like that. */
1031 if (last_component (newname) != newname)
1032 error (1, 0, "protocol error: Copy-file tried to specify directory");
1034 if (unlink_file (newname) && !existence_error (errno))
1035 error (0, errno, "unable to remove %s", newname);
1036 copy_file (filename, newname);
1041 handle_copy_file( char *args, int len )
1043 call_in_directory (args, copy_a_file, (char *)NULL);
1047 static void read_counted_file (char *, char *);
1049 /* Read from the server the count for the length of a file, then read
1050 the contents of that file and write them to FILENAME. FULLNAME is
1051 the name of the file for use in error messages. FIXME-someday:
1052 extend this to deal with compressed files and make update_entries
1053 use it. On error, gives a fatal error. */
1055 read_counted_file( char *filename, char *fullname )
1061 /* Pointers in buf to the place to put data which will be read,
1062 and the data which needs to be written, respectively. */
1065 /* Number of bytes left to read and number of bytes in buf waiting to
1066 be written, respectively. */
1072 read_line (&size_string);
1073 if (size_string[0] == 'z')
1075 protocol error: compressed files not supported for that operation");
1076 /* FIXME: should be doing more error checking, probably. Like using
1077 strtoul and making sure we used up the whole line. */
1078 size = atoi (size_string);
1081 /* A more sophisticated implementation would use only a limited amount
1082 of buffer space (8K perhaps), and read that much at a time. We allocate
1083 a buffer for the whole file only to make it easy to keep track what
1084 needs to be read and written. */
1085 buf = xmalloc (size);
1087 /* FIXME-someday: caller should pass in a flag saying whether it
1088 is binary or not. I haven't carefully looked into whether
1089 CVS/Template files should use local text file conventions or
1091 fp = CVS_FOPEN (filename, "wb");
1093 error (1, errno, "cannot write %s", fullname);
1098 while (nread > 0 || nwrite > 0)
1104 n = try_read_from_server (pread, nread);
1112 n = fwrite (pwrite, 1, nwrite, fp);
1114 error (1, errno, "cannot write %s", fullname);
1120 if (fclose (fp) < 0)
1121 error (1, errno, "cannot close %s", fullname);
1124 /* OK, we want to swallow the "U foo.c" response and then output it only
1125 if we can update the file. In the future we probably want some more
1126 systematic approach to parsing tagged text, but for now we keep it
1127 ad hoc. "Why," I hear you cry, "do we not just look at the
1128 Update-existing and Created responses?" That is an excellent question,
1129 and the answer is roughly conservatism/laziness--I haven't read through
1130 update.c enough to figure out the exact correspondence or lack thereof
1131 between those responses and a "U foo.c" line (note that Merged, from
1132 join_file, can be either "C foo" or "U foo" depending on the context). */
1133 /* Nonzero if we have seen +updated and not -updated. */
1134 static int updated_seen;
1135 /* Filename from an "fname" tagged response within +updated/-updated. */
1136 static char *updated_fname;
1138 /* This struct is used to hold data when reading the +importmergecmd
1139 and -importmergecmd tags. We put the variables in a struct only
1140 for namespace issues. FIXME: As noted above, we need to develop a
1141 more systematic approach. */
1144 /* Nonzero if we have seen +importmergecmd and not -importmergecmd. */
1146 /* Number of conflicts, from a "conflicts" tagged response. */
1148 /* First merge tag, from a "mergetag1" tagged response. */
1150 /* Second merge tag, from a "mergetag2" tagged response. */
1152 /* Repository, from a "repository" tagged response. */
1156 /* Nonzero if we should arrange to return with a failure exit status. */
1157 static int failure_exit;
1161 * The time stamp of the last file we registered.
1163 static time_t last_register_time;
1166 * The Checksum response gives the checksum for the file transferred
1167 * over by the next Updated, Merged or Patch response. We just store
1168 * it here, and then check it in update_entries.
1171 static int stored_checksum_valid;
1172 static unsigned char stored_checksum[16];
1175 handle_checksum( char *args, int len )
1181 if (stored_checksum_valid)
1182 error (1, 0, "Checksum received before last one was used");
1186 for (i = 0; i < 16; i++)
1192 stored_checksum[i] = (char) strtol (buf, &bufend, 16);
1193 if (bufend != buf + 2)
1197 if (i < 16 || *s != '\0')
1198 error (1, 0, "Invalid Checksum response: `%s'", args);
1200 stored_checksum_valid = 1;
1203 /* Mode that we got in a "Mode" response (malloc'd), or NULL if none. */
1204 static char *stored_mode;
1206 static void handle_mode (char *, int);
1209 handle_mode( char *args, int len )
1211 if (stored_mode != NULL)
1212 error (1, 0, "protocol error: duplicate Mode");
1213 stored_mode = xstrdup (args);
1216 /* Nonzero if time was specified in Mod-time. */
1217 static int stored_modtime_valid;
1218 /* Time specified in Mod-time. */
1219 static time_t stored_modtime;
1221 static void handle_mod_time (char *, int);
1224 handle_mod_time( char *args, int len )
1226 if (stored_modtime_valid)
1227 error (0, 0, "protocol error: duplicate Mod-time");
1228 stored_modtime = get_date (args, NULL);
1229 if (stored_modtime == (time_t) -1)
1230 error (0, 0, "protocol error: cannot parse date %s", args);
1232 stored_modtime_valid = 1;
1236 * If we receive a patch, but the patch program fails to apply it, we
1237 * want to request the original file. We keep a list of files whose
1238 * patches have failed.
1241 char **failed_patches;
1242 int failed_patches_count;
1244 struct update_entries_data
1248 * We are just getting an Entries line; the local file is
1251 UPDATE_ENTRIES_CHECKIN,
1252 /* We are getting the file contents as well. */
1253 UPDATE_ENTRIES_UPDATE,
1255 * We are getting a patch against the existing local file, not
1256 * an entire new file.
1258 UPDATE_ENTRIES_PATCH,
1260 * We are getting an RCS change text (diff -n output) against
1261 * the existing local file, not an entire new file.
1263 UPDATE_ENTRIES_RCS_DIFF
1267 /* We are replacing an existing file. */
1268 UPDATE_ENTRIES_EXISTING,
1269 /* We are creating a new file. */
1271 /* We don't know whether it is existing or new. */
1272 UPDATE_ENTRIES_EXISTING_OR_NEW
1276 * String to put in the timestamp field or NULL to use the timestamp
1282 /* Update the Entries line for this file. */
1284 update_entries( char *data_arg, List *ent_list, char *short_pathname,
1288 struct update_entries_data *data = (struct update_entries_data *)data_arg;
1293 /* Timestamp field. Always empty according to the protocol. */
1295 char *options = NULL;
1299 char *scratch_entries = NULL;
1302 #ifdef UTIME_EXPECTS_WRITABLE
1303 int change_it_back = 0;
1306 read_line (&entries_line);
1309 * Parse the entries line.
1311 scratch_entries = xstrdup (entries_line);
1313 if (scratch_entries[0] != '/')
1314 error (1, 0, "bad entries line `%s' from server", entries_line);
1315 user = scratch_entries + 1;
1316 if ((cp = strchr (user, '/')) == NULL)
1317 error (1, 0, "bad entries line `%s' from server", entries_line);
1320 if ((cp = strchr (vn, '/')) == NULL)
1321 error (1, 0, "bad entries line `%s' from server", entries_line);
1325 if ((cp = strchr (ts, '/')) == NULL)
1326 error (1, 0, "bad entries line `%s' from server", entries_line);
1329 if ((cp = strchr (options, '/')) == NULL)
1330 error (1, 0, "bad entries line `%s' from server", entries_line);
1334 /* If a slash ends the tag_or_date, ignore everything after it. */
1335 cp = strchr (tag_or_date, '/');
1338 if (*tag_or_date == 'T')
1339 tag = tag_or_date + 1;
1340 else if (*tag_or_date == 'D')
1341 date = tag_or_date + 1;
1343 /* Done parsing the entries line. */
1345 if (data->contents == UPDATE_ENTRIES_UPDATE
1346 || data->contents == UPDATE_ENTRIES_PATCH
1347 || data->contents == UPDATE_ENTRIES_RCS_DIFF)
1353 char *temp_filename;
1357 read_line (&mode_string);
1359 read_line (&size_string);
1360 if (size_string[0] == 'z')
1363 size = atoi (size_string+1);
1368 size = atoi (size_string);
1372 /* Note that checking this separately from writing the file is
1373 a race condition: if the existence or lack thereof of the
1374 file changes between now and the actual calls which
1375 operate on it, we lose. However (a) there are so many
1376 cases, I'm reluctant to try to fix them all, (b) in some
1377 cases the system might not even have a system call which
1378 does the right thing, and (c) it isn't clear this needs to
1380 if (data->existp == UPDATE_ENTRIES_EXISTING
1381 && !isfile (filename))
1382 /* Emit a warning and update the file anyway. */
1383 error (0, 0, "warning: %s unexpectedly disappeared",
1386 if (data->existp == UPDATE_ENTRIES_NEW
1387 && isfile (filename))
1389 /* Emit a warning and refuse to update the file; we don't want
1390 to clobber a user's file. */
1394 /* size should be unsigned, but until we get around to fixing
1395 that, work around it. */
1400 /* This error might be confusing; it isn't really clear to
1401 the user what to do about it. Keep in mind that it has
1402 several causes: (1) something/someone creates the file
1403 during the time that CVS is running, (2) the repository
1404 has two files whose names clash for the client because
1405 of case-insensitivity or similar causes, See 3 for
1406 additional notes. (3) a special case of this is that a
1407 file gets renamed for example from a.c to A.C. A
1408 "cvs update" on a case-insensitive client will get this
1409 error. In this case and in case 2, the filename
1410 (short_pathname) printed in the error message will likely _not_
1411 have the same case as seen by the user in a directory listing.
1412 (4) the client has a file which the server doesn't know
1413 about (e.g. "? foo" file), and that name clashes with a file
1414 the server does know about, (5) classify.c will print the same
1415 message for other reasons.
1417 I hope the above paragraph makes it clear that making this
1418 clearer is not a one-line fix. */
1419 error (0, 0, "move away `%s'; it is in the way", short_pathname);
1420 if (updated_fname != NULL)
1422 cvs_output ("C ", 0);
1423 cvs_output (updated_fname, 0);
1424 cvs_output ("\n", 1);
1428 discard_file_and_return:
1429 /* Now read and discard the file contents. */
1432 while (nread < usize)
1434 toread = usize - nread;
1435 if (toread > sizeof buf)
1436 toread = sizeof buf;
1438 nread += try_read_from_server (buf, toread);
1444 free (scratch_entries);
1445 free (entries_line);
1447 /* The Mode, Mod-time, and Checksum responses should not carry
1448 over to a subsequent Created (or whatever) response, even
1449 in the error case. */
1450 if (stored_mode != NULL)
1455 stored_modtime_valid = 0;
1456 stored_checksum_valid = 0;
1458 if (updated_fname != NULL)
1460 free (updated_fname);
1461 updated_fname = NULL;
1466 temp_filename = xmalloc (strlen (filename) + 80);
1467 #ifdef USE_VMS_FILENAMES
1468 /* A VMS rename of "blah.dat" to "foo" to implies a
1469 destination of "foo.dat" which is unfortinate for CVS */
1470 sprintf (temp_filename, "%s_new_", filename);
1472 #ifdef _POSIX_NO_TRUNC
1473 sprintf (temp_filename, ".new.%.9s", filename);
1474 #else /* _POSIX_NO_TRUNC */
1475 sprintf (temp_filename, ".new.%s", filename);
1476 #endif /* _POSIX_NO_TRUNC */
1477 #endif /* USE_VMS_FILENAMES */
1479 buf = xmalloc (size);
1481 /* Some systems, like OS/2 and Windows NT, end lines with CRLF
1482 instead of just LF. Format translation is done in the C
1483 library I/O funtions. Here we tell them whether or not to
1484 convert -- if this file is marked "binary" with the RCS -kb
1485 flag, then we don't want to convert, else we do (because
1486 CVS assumes text files by default). */
1489 bin = !(strcmp (options, "-kb"));
1493 if (data->contents == UPDATE_ENTRIES_RCS_DIFF)
1495 /* This is an RCS change text. We just hold the change
1500 "server error: gzip invalid with RCS change text");
1502 read_from_server (buf, size);
1508 fd = CVS_OPEN (temp_filename,
1509 (O_WRONLY | O_CREAT | O_TRUNC
1510 | (bin ? OPEN_BINARY : 0)),
1515 /* I can see a case for making this a fatal error; for
1516 a condition like disk full or network unreachable
1517 (for a file server), carrying on and giving an
1518 error on each file seems unnecessary. But if it is
1519 a permission problem, or some such, then it is
1520 entirely possible that future files will not have
1521 the same problem. */
1522 error (0, errno, "cannot write %s", short_pathname);
1523 goto discard_file_and_return;
1528 read_from_server (buf, size);
1532 if (gunzip_and_write (fd, short_pathname,
1533 (unsigned char *) buf, size))
1534 error (1, 0, "aborting due to compression error");
1536 else if (write (fd, buf, size) != size)
1537 error (1, errno, "writing %s", short_pathname);
1541 error (1, errno, "writing %s", short_pathname);
1544 /* This is after we have read the file from the net (a change
1545 from previous versions, where the server would send us
1546 "M U foo.c" before Update-existing or whatever), but before
1547 we finish writing the file (arguably a bug). The timing
1548 affects a user who wants status info about how far we have
1549 gotten, and also affects whether "U foo.c" appears in addition
1550 to various error messages. */
1551 if (updated_fname != NULL)
1553 cvs_output ("U ", 0);
1554 cvs_output (updated_fname, 0);
1555 cvs_output ("\n", 1);
1556 free (updated_fname);
1562 if (data->contents == UPDATE_ENTRIES_UPDATE)
1564 rename_file (temp_filename, filename);
1566 else if (data->contents == UPDATE_ENTRIES_PATCH)
1568 /* You might think we could just leave Patched out of
1569 Valid-responses and not get this response. However, if
1570 memory serves, the CVS 1.9 server bases this on -u
1571 (update-patches), and there is no way for us to send -u
1572 or not based on whether the server supports "Rcs-diff".
1574 Fall back to transmitting entire files. */
1585 /* Handle UPDATE_ENTRIES_RCS_DIFF. */
1587 if (!isfile (filename))
1588 error (1, 0, "patch original file %s does not exist",
1594 get_file (filename, short_pathname, bin ? FOPEN_BINARY_READ : "r",
1595 &filebuf, &filebufsize, &nread);
1596 /* At this point the contents of the existing file are in
1597 FILEBUF, and the length of the contents is in NREAD.
1598 The contents of the patch from the network are in BUF,
1599 and the length of the patch is in SIZE. */
1601 if (! rcs_change_text (short_pathname, filebuf, nread, buf, size,
1602 &patchedbuf, &patchedlen))
1606 if (stored_checksum_valid)
1608 struct cvs_MD5Context context;
1609 unsigned char checksum[16];
1611 /* We have a checksum. Check it before writing
1612 the file out, so that we don't have to read it
1614 cvs_MD5Init (&context);
1615 cvs_MD5Update (&context,
1616 (unsigned char *) patchedbuf, patchedlen);
1617 cvs_MD5Final (checksum, &context);
1618 if (memcmp (checksum, stored_checksum, 16) != 0)
1621 "checksum failure after patch to %s; will refetch",
1627 stored_checksum_valid = 0;
1634 e = open_file (temp_filename,
1635 bin ? FOPEN_BINARY_WRITE : "w");
1636 if (fwrite (patchedbuf, 1, patchedlen, e) != patchedlen)
1637 error (1, errno, "cannot write %s", temp_filename);
1638 if (fclose (e) == EOF)
1639 error (1, errno, "cannot close %s", temp_filename);
1640 rename_file (temp_filename, filename);
1649 free (temp_filename);
1651 if (stored_checksum_valid && ! patch_failed)
1654 struct cvs_MD5Context context;
1655 unsigned char buf[8192];
1657 unsigned char checksum[16];
1660 * Compute the MD5 checksum. This will normally only be
1661 * used when receiving a patch, so we always compute it
1662 * here on the final file, rather than on the received
1665 * Note that if the file is a text file, we should read it
1666 * here using text mode, so its lines will be terminated the same
1667 * way they were transmitted.
1669 e = CVS_FOPEN (filename, "r");
1671 error (1, errno, "could not open %s", short_pathname);
1673 cvs_MD5Init (&context);
1674 while ((len = fread (buf, 1, sizeof buf, e)) != 0)
1675 cvs_MD5Update (&context, buf, len);
1677 error (1, errno, "could not read %s", short_pathname);
1678 cvs_MD5Final (checksum, &context);
1682 stored_checksum_valid = 0;
1684 if (memcmp (checksum, stored_checksum, 16) != 0)
1686 if (data->contents != UPDATE_ENTRIES_PATCH)
1687 error (1, 0, "checksum failure on %s",
1691 "checksum failure after patch to %s; will refetch",
1700 /* Save this file to retrieve later. */
1701 failed_patches = (char **) xrealloc ((char *) failed_patches,
1702 ((failed_patches_count + 1)
1703 * sizeof (char *)));
1704 failed_patches[failed_patches_count] = xstrdup (short_pathname);
1705 ++failed_patches_count;
1707 stored_checksum_valid = 0;
1711 free (scratch_entries);
1712 free (entries_line);
1718 int status = change_mode (filename, mode_string, 1);
1720 error (0, status, "cannot change mode of %s", short_pathname);
1727 if (stored_mode != NULL)
1729 change_mode (filename, stored_mode, 1);
1734 if (stored_modtime_valid)
1738 memset (&t, 0, sizeof (t));
1739 t.modtime = stored_modtime;
1740 (void) time (&t.actime);
1742 #ifdef UTIME_EXPECTS_WRITABLE
1743 if (!iswritable (filename))
1745 xchmod (filename, 1);
1748 #endif /* UTIME_EXPECTS_WRITABLE */
1750 if (utime (filename, &t) < 0)
1751 error (0, errno, "cannot set time on %s", filename);
1753 #ifdef UTIME_EXPECTS_WRITABLE
1756 xchmod (filename, 0);
1759 #endif /* UTIME_EXPECTS_WRITABLE */
1761 stored_modtime_valid = 0;
1765 * Process the entries line. Do this after we've written the file,
1766 * since we need the timestamp.
1768 if (strcmp (cvs_cmd_name, "export") != 0)
1770 char *local_timestamp;
1771 char *file_timestamp;
1773 (void) time (&last_register_time);
1775 local_timestamp = data->timestamp;
1776 if (local_timestamp == NULL || ts[0] == '+')
1777 file_timestamp = time_stamp (filename);
1779 file_timestamp = NULL;
1782 * These special version numbers signify that it is not up to
1783 * date. Create a dummy timestamp which will never compare
1784 * equal to the timestamp of the file.
1786 if (vn[0] == '\0' || strcmp (vn, "0") == 0 || vn[0] == '-')
1787 local_timestamp = "dummy timestamp";
1788 else if (local_timestamp == NULL)
1790 local_timestamp = file_timestamp;
1792 /* Checking for cvs_cmd_name of "commit" doesn't seem like
1793 the cleanest way to handle this, but it seem to roughly
1794 parallel what the :local: code which calls
1795 mark_up_to_date ends up amounting to. Some day, should
1796 think more about what the Checked-in response means
1797 vis-a-vis both Entries and Base and clarify
1798 cvsclient.texi accordingly. */
1800 if (!strcmp (cvs_cmd_name, "commit"))
1801 mark_up_to_date (filename);
1804 Register (ent_list, filename, vn, local_timestamp,
1805 options, tag, date, ts[0] == '+' ? file_timestamp : NULL);
1808 free (file_timestamp);
1811 free (scratch_entries);
1812 free (entries_line);
1816 handle_checked_in( char *args, int len )
1818 struct update_entries_data dat;
1819 dat.contents = UPDATE_ENTRIES_CHECKIN;
1820 dat.existp = UPDATE_ENTRIES_EXISTING_OR_NEW;
1821 dat.timestamp = NULL;
1822 call_in_directory (args, update_entries, (char *)&dat);
1826 handle_new_entry( char *args, int len )
1828 struct update_entries_data dat;
1829 dat.contents = UPDATE_ENTRIES_CHECKIN;
1830 dat.existp = UPDATE_ENTRIES_EXISTING_OR_NEW;
1831 dat.timestamp = "dummy timestamp from new-entry";
1832 call_in_directory (args, update_entries, (char *)&dat);
1836 handle_updated( char *args, int len )
1838 struct update_entries_data dat;
1839 dat.contents = UPDATE_ENTRIES_UPDATE;
1840 dat.existp = UPDATE_ENTRIES_EXISTING_OR_NEW;
1841 dat.timestamp = NULL;
1842 call_in_directory (args, update_entries, (char *)&dat);
1845 static void handle_created (char *, int);
1848 handle_created( char *args, int len )
1850 struct update_entries_data dat;
1851 dat.contents = UPDATE_ENTRIES_UPDATE;
1852 dat.existp = UPDATE_ENTRIES_NEW;
1853 dat.timestamp = NULL;
1854 call_in_directory (args, update_entries, (char *)&dat);
1857 static void handle_update_existing (char *, int);
1860 handle_update_existing( char *args, int len )
1862 struct update_entries_data dat;
1863 dat.contents = UPDATE_ENTRIES_UPDATE;
1864 dat.existp = UPDATE_ENTRIES_EXISTING;
1865 dat.timestamp = NULL;
1866 call_in_directory (args, update_entries, (char *)&dat);
1870 handle_merged( char *args, int len )
1872 struct update_entries_data dat;
1873 dat.contents = UPDATE_ENTRIES_UPDATE;
1874 /* Think this could be UPDATE_ENTRIES_EXISTING, but just in case... */
1875 dat.existp = UPDATE_ENTRIES_EXISTING_OR_NEW;
1876 dat.timestamp = "Result of merge";
1877 call_in_directory (args, update_entries, (char *)&dat);
1881 handle_patched( char *args, int len )
1883 struct update_entries_data dat;
1884 dat.contents = UPDATE_ENTRIES_PATCH;
1885 /* Think this could be UPDATE_ENTRIES_EXISTING, but just in case... */
1886 dat.existp = UPDATE_ENTRIES_EXISTING_OR_NEW;
1887 dat.timestamp = NULL;
1888 call_in_directory (args, update_entries, (char *)&dat);
1892 handle_rcs_diff( char *args, int len )
1894 struct update_entries_data dat;
1895 dat.contents = UPDATE_ENTRIES_RCS_DIFF;
1896 /* Think this could be UPDATE_ENTRIES_EXISTING, but just in case... */
1897 dat.existp = UPDATE_ENTRIES_EXISTING_OR_NEW;
1898 dat.timestamp = NULL;
1899 call_in_directory (args, update_entries, (char *)&dat);
1903 remove_entry( char *data, List *ent_list, char *short_pathname,
1906 Scratch_Entry (ent_list, filename);
1910 handle_remove_entry( char *args, int len )
1912 call_in_directory (args, remove_entry, (char *)NULL);
1916 remove_entry_and_file( char *data, List *ent_list, char *short_pathname,
1919 Scratch_Entry (ent_list, filename);
1920 /* Note that we don't ignore existence_error's here. The server
1921 should be sending Remove-entry rather than Removed in cases
1922 where the file does not exist. And if the user removes the
1923 file halfway through a cvs command, we should be printing an
1925 if (unlink_file (filename) < 0)
1926 error (0, errno, "unable to remove %s", short_pathname);
1930 handle_removed( char *args, int len )
1932 call_in_directory (args, remove_entry_and_file, (char *)NULL);
1935 /* Is this the top level (directory containing CVSROOT)? */
1937 is_cvsroot_level( char *pathname )
1939 if (strcmp (toplevel_repos, current_parsed_root->directory) != 0)
1942 return strchr (pathname, '/') == NULL;
1946 set_static( char *data, List *ent_list, char *short_pathname, char *filename )
1949 fp = open_file (CVSADM_ENTSTAT, "w+");
1950 if (fclose (fp) == EOF)
1951 error (1, errno, "cannot close %s", CVSADM_ENTSTAT);
1955 handle_set_static_directory( char *args, int len )
1957 if (strcmp (cvs_cmd_name, "export") == 0)
1959 /* Swallow the repository. */
1963 call_in_directory (args, set_static, (char *)NULL);
1967 clear_static( char *data, List *ent_list, char *short_pathname,
1970 if (unlink_file (CVSADM_ENTSTAT) < 0 && ! existence_error (errno))
1971 error (1, errno, "cannot remove file %s", CVSADM_ENTSTAT);
1975 handle_clear_static_directory( char *pathname, int len )
1977 if (strcmp (cvs_cmd_name, "export") == 0)
1979 /* Swallow the repository. */
1984 if (is_cvsroot_level (pathname))
1987 * Top level (directory containing CVSROOT). This seems to normally
1988 * lack a CVS directory, so don't try to create files in it.
1992 call_in_directory (pathname, clear_static, (char *)NULL);
1996 set_sticky( char *data, List *ent_list, char *short_pathname, char *filename )
2001 read_line (&tagspec);
2003 /* FIXME-update-dir: error messages should include the directory. */
2004 f = CVS_FOPEN (CVSADM_TAG, "w+");
2007 /* Making this non-fatal is a bit of a kludge (see dirs2
2008 in testsuite). A better solution would be to avoid having
2009 the server tell us about a directory we shouldn't be doing
2010 anything with anyway (e.g. by handling directory
2011 addition/removal better). */
2012 error (0, errno, "cannot open %s", CVSADM_TAG);
2016 if (fprintf (f, "%s\n", tagspec) < 0)
2017 error (1, errno, "writing %s", CVSADM_TAG);
2018 if (fclose (f) == EOF)
2019 error (1, errno, "closing %s", CVSADM_TAG);
2024 handle_set_sticky( char *pathname, int len )
2026 if (strcmp (cvs_cmd_name, "export") == 0)
2028 /* Swallow the repository. */
2030 /* Swallow the tag line. */
2034 if (is_cvsroot_level (pathname))
2037 * Top level (directory containing CVSROOT). This seems to normally
2038 * lack a CVS directory, so don't try to create files in it.
2041 /* Swallow the repository. */
2043 /* Swallow the tag line. */
2048 call_in_directory (pathname, set_sticky, (char *)NULL);
2052 clear_sticky( char *data, List *ent_list, char *short_pathname,
2055 if (unlink_file (CVSADM_TAG) < 0 && ! existence_error (errno))
2056 error (1, errno, "cannot remove %s", CVSADM_TAG);
2060 handle_clear_sticky( char *pathname, int len )
2062 if (strcmp (cvs_cmd_name, "export") == 0)
2064 /* Swallow the repository. */
2069 if (is_cvsroot_level (pathname))
2072 * Top level (directory containing CVSROOT). This seems to normally
2073 * lack a CVS directory, so don't try to create files in it.
2078 call_in_directory (pathname, clear_sticky, (char *)NULL);
2082 static void template (char *, List *, char *, char *);
2085 template( char *data, List *ent_list, char *short_pathname, char *filename )
2087 char *buf = xmalloc ( strlen ( short_pathname )
2088 + strlen ( CVSADM_TEMPLATE )
2090 sprintf ( buf, "%s/%s", short_pathname, CVSADM_TEMPLATE );
2091 read_counted_file ( CVSADM_TEMPLATE, buf );
2095 static void handle_template (char *, int);
2098 handle_template( char *pathname, int len )
2100 call_in_directory (pathname, template, NULL);
2104 clear_template( char *data, List *ent_list, char *short_pathname,
2107 if (unlink_file (CVSADM_TEMPLATE) < 0 && ! existence_error (errno))
2108 error (1, errno, "cannot remove %s", CVSADM_TEMPLATE);
2112 handle_clear_template( char *pathname, int len )
2114 call_in_directory (pathname, clear_template, NULL);
2121 struct save_dir *next;
2124 struct save_dir *prune_candidates;
2127 add_prune_candidate (const char *dir)
2131 if ((dir[0] == '.' && dir[1] == '\0')
2132 || (prune_candidates != NULL
2133 && strcmp (dir, prune_candidates->dir) == 0))
2135 p = (struct save_dir *) xmalloc (sizeof (struct save_dir));
2136 p->dir = xstrdup (dir);
2137 p->next = prune_candidates;
2138 prune_candidates = p;
2141 static void process_prune_candidates (void);
2144 process_prune_candidates( void )
2149 if (toplevel_wd != NULL)
2151 if (CVS_CHDIR (toplevel_wd) < 0)
2152 error (1, errno, "could not chdir to %s", toplevel_wd);
2154 for (p = prune_candidates; p != NULL; )
2156 if (isemptydir (p->dir, 1))
2160 if (unlink_file_dir (p->dir) < 0)
2161 error (0, errno, "cannot remove %s", p->dir);
2162 b = strrchr (p->dir, '/');
2164 Subdir_Deregister ((List *) NULL, (char *) NULL, p->dir);
2168 Subdir_Deregister ((List *) NULL, p->dir, b + 1);
2176 prune_candidates = NULL;
2179 /* Send a Repository line. */
2181 static char *last_repos;
2182 static char *last_update_dir;
2187 send_repository (const char *dir, const char *repos, const char *update_dir)
2191 /* FIXME: this is probably not the best place to check; I wish I
2192 * knew where in here's callers to really trap this bug. To
2193 * reproduce the bug, just do this:
2197 * cvs -d some_repos update foo
2199 * Poof, CVS seg faults and dies! It's because it's trying to
2200 * send a NULL string to the server but dies in send_to_server.
2201 * That string was supposed to be the repository, but it doesn't
2202 * get set because there's no CVSADM dir, and somehow it's not
2203 * getting set from the -d argument either... ?
2207 /* Lame error. I want a real fix but can't stay up to track
2208 this down right now. */
2209 error (1, 0, "no repository");
2212 if (update_dir == NULL || update_dir[0] == '\0')
2215 if (last_repos != NULL
2216 && strcmp (repos, last_repos) == 0
2217 && last_update_dir != NULL
2218 && strcmp (update_dir, last_update_dir) == 0)
2219 /* We've already sent it. */
2222 if (client_prune_dirs)
2223 add_prune_candidate (update_dir);
2225 /* Add a directory name to the list of those sent to the
2227 if (update_dir && (*update_dir != '\0')
2228 && (strcmp (update_dir, ".") != 0)
2229 && (findnode (dirs_sent_to_server, update_dir) == NULL))
2233 n->type = NT_UNKNOWN;
2234 n->key = xstrdup (update_dir);
2237 if (addnode (dirs_sent_to_server, n))
2238 error (1, 0, "cannot add directory %s to list", n->key);
2241 /* 80 is large enough for any of CVSADM_*. */
2242 adm_name = xmalloc (strlen (dir) + 80);
2244 send_to_server ("Directory ", 0);
2246 /* Send the directory name. I know that this
2247 sort of duplicates code elsewhere, but each
2248 case seems slightly different... */
2250 const char *p = update_dir;
2253 assert (*p != '\012');
2257 send_to_server (buf, 1);
2262 send_to_server (buf, 1);
2267 send_to_server ("\012", 1);
2268 send_to_server (repos, 0);
2269 send_to_server ("\012", 1);
2271 if (supported_request ("Static-directory"))
2276 strcat (adm_name, dir);
2277 strcat (adm_name, "/");
2279 strcat (adm_name, CVSADM_ENTSTAT);
2280 if (isreadable (adm_name))
2282 send_to_server ("Static-directory\012", 0);
2285 if (supported_request ("Sticky"))
2289 strcpy (adm_name, CVSADM_TAG);
2291 sprintf (adm_name, "%s/%s", dir, CVSADM_TAG);
2293 f = CVS_FOPEN (adm_name, "r");
2296 if (! existence_error (errno))
2297 error (1, errno, "reading %s", adm_name);
2303 send_to_server ("Sticky ", 0);
2304 while (fgets (line, sizeof (line), f) != NULL)
2306 send_to_server (line, 0);
2307 nl = strchr (line, '\n');
2312 send_to_server ("\012", 1);
2313 if (fclose (f) == EOF)
2314 error (0, errno, "closing %s", adm_name);
2318 if (last_repos != NULL)
2320 if (last_update_dir != NULL)
2321 free (last_update_dir);
2322 last_repos = xstrdup (repos);
2323 last_update_dir = xstrdup (update_dir);
2328 /* Send a Repository line and set toplevel_repos. */
2331 send_a_repository (const char *dir, const char *repository,
2332 const char *update_dir_in)
2334 char *update_dir = xstrdup (update_dir_in);
2336 if (toplevel_repos == NULL && repository != NULL)
2338 if (update_dir[0] == '\0'
2339 || (update_dir[0] == '.' && update_dir[1] == '\0'))
2340 toplevel_repos = xstrdup (repository);
2344 * Get the repository from a CVS/Repository file if update_dir
2345 * is absolute. This is not correct in general, because
2346 * the CVS/Repository file might not be the top-level one.
2347 * This is for cases like "cvs update /foo/bar" (I'm not
2348 * sure it matters what toplevel_repos we get, but it does
2349 * matter that we don't hit the "internal error" code below).
2351 if (update_dir[0] == '/')
2352 toplevel_repos = Name_Repository (update_dir, update_dir);
2356 * Guess the repository of that directory by looking at a
2357 * subdirectory and removing as many pathname components
2358 * as are in update_dir. I think that will always (or at
2359 * least almost always) be 1.
2361 * So this deals with directories which have been
2362 * renamed, though it doesn't necessarily deal with
2363 * directories which have been put inside other
2364 * directories (and cvs invoked on the containing
2365 * directory). I'm not sure the latter case needs to
2368 * 21 Aug 1998: Well, Mr. Above-Comment-Writer, it
2369 * does need to work after all. When we are using the
2370 * client in a multi-cvsroot environment, it will be
2371 * fairly common that we have the above case (e.g.,
2372 * cwd checked out from one repository but
2373 * subdirectory checked out from another). We can't
2374 * assume that by walking up a directory in our wd we
2375 * necessarily walk up a directory in the repository.
2378 * This gets toplevel_repos wrong for "cvs update ../foo"
2379 * but I'm not sure toplevel_repos matters in that case.
2382 int repository_len, update_dir_len;
2384 strip_trailing_slashes (update_dir);
2386 repository_len = strlen (repository);
2387 update_dir_len = strlen (update_dir);
2389 /* Try to remove the path components in UPDATE_DIR
2390 from REPOSITORY. If the path elements don't exist
2391 in REPOSITORY, or the removal of those path
2392 elements mean that we "step above"
2393 current_parsed_root->directory, set toplevel_repos to
2394 current_parsed_root->directory. */
2395 if ((repository_len > update_dir_len)
2396 && (strcmp (repository + repository_len - update_dir_len,
2398 /* TOPLEVEL_REPOS shouldn't be above current_parsed_root->directory */
2399 && ((size_t)(repository_len - update_dir_len)
2400 > strlen (current_parsed_root->directory)))
2402 /* The repository name contains UPDATE_DIR. Set
2403 toplevel_repos to the repository name without
2406 toplevel_repos = xmalloc (repository_len - update_dir_len);
2407 /* Note that we don't copy the trailing '/'. */
2408 strncpy (toplevel_repos, repository,
2409 repository_len - update_dir_len - 1);
2410 toplevel_repos[repository_len - update_dir_len - 1] = '\0';
2414 toplevel_repos = xstrdup (current_parsed_root->directory);
2420 send_repository (dir, repository, update_dir);
2426 /* The "expanded" modules. */
2427 static int modules_count;
2428 static int modules_allocated;
2429 static char **modules_vector;
2432 handle_module_expansion( char *args, int len )
2434 if (modules_vector == NULL)
2436 modules_allocated = 1; /* Small for testing */
2437 modules_vector = (char **) xmalloc
2438 (modules_allocated * sizeof (modules_vector[0]));
2440 else if (modules_count >= modules_allocated)
2442 modules_allocated *= 2;
2443 modules_vector = (char **) xrealloc
2444 ((char *) modules_vector,
2445 modules_allocated * sizeof (modules_vector[0]));
2447 modules_vector[modules_count] = xmalloc (strlen (args) + 1);
2448 strcpy (modules_vector[modules_count], args);
2452 /* Original, not "expanded" modules. */
2453 static int module_argc;
2454 static char **module_argv;
2457 client_expand_modules( int argc, char **argv, int local )
2463 module_argv = (char **) xmalloc ((argc + 1) * sizeof (module_argv[0]));
2464 for (i = 0; i < argc; ++i)
2465 module_argv[i] = xstrdup (argv[i]);
2466 module_argv[argc] = NULL;
2468 for (i = 0; i < argc; ++i)
2470 send_a_repository ("", current_parsed_root->directory, "");
2472 send_to_server ("expand-modules\012", 0);
2474 errs = get_server_responses ();
2475 if (last_repos != NULL)
2478 if (last_update_dir != NULL)
2479 free (last_update_dir);
2480 last_update_dir = NULL;
2482 error (errs, 0, "cannot expand modules");
2486 client_send_expansions( int local, char *where, int build_dirs )
2491 /* Send the original module names. The "expanded" module name might
2492 not be suitable as an argument to a co request (e.g. it might be
2493 the result of a -d argument in the modules file). It might be
2494 cleaner if we genuinely expanded module names, all the way to a
2495 local directory and repository, but that isn't the way it works
2497 send_file_names (module_argc, module_argv, 0);
2499 for (i = 0; i < modules_count; ++i)
2501 argv[0] = where ? where : modules_vector[i];
2502 if (isfile (argv[0]))
2503 send_files (1, argv, local, 0, build_dirs ? SEND_BUILD_DIRS : 0);
2505 send_a_repository ("", current_parsed_root->directory, "");
2509 client_nonexpanded_setup( void )
2511 send_a_repository ("", current_parsed_root->directory, "");
2514 /* Receive a cvswrappers line from the server; it must be a line
2515 containing an RCS option (e.g., "*.exe -k 'b'").
2517 Note that this doesn't try to handle -t/-f options (which are a
2518 whole separate issue which noone has thought much about, as far
2521 We need to know the keyword expansion mode so we know whether to
2522 read the file in text or binary mode. */
2525 handle_wrapper_rcs_option( char *args, int len )
2529 /* Enforce the notes in cvsclient.texi about how the response is not
2530 as free-form as it looks. */
2531 p = strchr (args, ' ');
2539 if (strchr (p, '\'') == NULL)
2542 /* Add server-side cvswrappers line to our wrapper list. */
2546 error (0, errno, "protocol error: ignoring invalid wrappers %s", args);
2551 handle_m( char *args, int len )
2553 /* In the case where stdout and stderr point to the same place,
2554 fflushing stderr will make output happen in the correct order.
2555 Often stderr will be line-buffered and this won't be needed,
2556 but not always (is that true? I think the comment is probably
2557 based on being confused between default buffering between
2558 stdout and stderr. But I'm not sure). */
2560 fwrite (args, len, sizeof (*args), stdout);
2561 putc ('\n', stdout);
2564 static void handle_mbinary (char *, int);
2567 handle_mbinary( char *args, int len )
2576 /* See comment at handle_m about (non)flush of stderr. */
2579 read_line (&size_string);
2580 size = atoi (size_string);
2583 /* OK, now get all the data. The algorithm here is that we read
2584 as much as the network wants to give us in
2585 try_read_from_server, and then we output it all, and then
2586 repeat, until we get all the data. */
2588 while (totalread < size)
2590 toread = size - totalread;
2591 if (toread > sizeof buf)
2592 toread = sizeof buf;
2594 nread = try_read_from_server (buf, toread);
2595 cvs_output_binary (buf, nread);
2601 handle_e( char *args, int len )
2603 /* In the case where stdout and stderr point to the same place,
2604 fflushing stdout will make output happen in the correct order. */
2606 fwrite (args, len, sizeof (*args), stderr);
2607 putc ('\n', stderr);
2612 handle_f( char *args, int len )
2617 static void handle_mt (char *, int);
2620 handle_mt( char *args, int len )
2626 /* See comment at handle_m for more details. */
2629 p = strchr (args, ' ');
2641 if (strcmp (tag, "+updated") == 0)
2643 else if (strcmp (tag, "+importmergecmd") == 0)
2644 importmergecmd.seen = 1;
2647 if (strcmp (tag, "-updated") == 0)
2649 else if (strcmp (tag, "-importmergecmd") == 0)
2653 /* Now that we have gathered the information, we can
2654 output the suggested merge command. */
2656 if (importmergecmd.conflicts == 0
2657 || importmergecmd.mergetag1 == NULL
2658 || importmergecmd.mergetag2 == NULL
2659 || importmergecmd.repository == NULL)
2662 "invalid server: incomplete importmergecmd tags");
2666 sprintf (buf, "\n%d conflicts created by this import.\n",
2667 importmergecmd.conflicts);
2668 cvs_output (buf, 0);
2669 cvs_output ("Use the following command to help the merge:\n\n",
2671 cvs_output ("\t", 1);
2672 cvs_output (program_name, 0);
2673 if (CVSroot_cmdline != NULL)
2675 cvs_output (" -d ", 0);
2676 cvs_output (CVSroot_cmdline, 0);
2678 cvs_output (" checkout -j", 0);
2679 cvs_output (importmergecmd.mergetag1, 0);
2680 cvs_output (" -j", 0);
2681 cvs_output (importmergecmd.mergetag2, 0);
2682 cvs_output (" ", 1);
2683 cvs_output (importmergecmd.repository, 0);
2684 cvs_output ("\n\n", 0);
2686 /* Clear the static variables so that everything is
2687 ready for any subsequent importmergecmd tag. */
2688 importmergecmd.conflicts = 0;
2689 free (importmergecmd.mergetag1);
2690 importmergecmd.mergetag1 = NULL;
2691 free (importmergecmd.mergetag2);
2692 importmergecmd.mergetag2 = NULL;
2693 free (importmergecmd.repository);
2694 importmergecmd.repository = NULL;
2696 importmergecmd.seen = 0;
2702 if (strcmp (tag, "fname") == 0)
2704 if (updated_fname != NULL)
2706 /* Output the previous message now. This can happen
2707 if there was no Update-existing or other such
2708 response, due to the -n global option. */
2709 cvs_output ("U ", 0);
2710 cvs_output (updated_fname, 0);
2711 cvs_output ("\n", 1);
2712 free (updated_fname);
2714 updated_fname = xstrdup (text);
2716 /* Swallow all other tags. Either they are extraneous
2717 or they reflect future extensions that we can
2720 else if (importmergecmd.seen)
2722 if (strcmp (tag, "conflicts") == 0)
2723 importmergecmd.conflicts = atoi (text);
2724 else if (strcmp (tag, "mergetag1") == 0)
2725 importmergecmd.mergetag1 = xstrdup (text);
2726 else if (strcmp (tag, "mergetag2") == 0)
2727 importmergecmd.mergetag2 = xstrdup (text);
2728 else if (strcmp (tag, "repository") == 0)
2729 importmergecmd.repository = xstrdup (text);
2730 /* Swallow all other tags. Either they are text for
2731 which we are going to print our own version when we
2732 see -importmergecmd, or they are future extensions
2733 we can safely ignore. */
2735 else if (strcmp (tag, "newline") == 0)
2737 else if (strcmp (tag, "date") == 0)
2739 char *date = format_date_alloc (text);
2740 printf ("%s", date);
2743 else if (text != NULL)
2744 printf ("%s", text);
2748 #endif /* CLIENT_SUPPORT */
2749 #if defined(CLIENT_SUPPORT) || defined(SERVER_SUPPORT)
2751 /* This table must be writeable if the server code is included. */
2752 struct response responses[] =
2754 #ifdef CLIENT_SUPPORT
2755 #define RSP_LINE(n, f, t, s) {n, f, t, s}
2756 #else /* ! CLIENT_SUPPORT */
2757 #define RSP_LINE(n, f, t, s) {n, s}
2758 #endif /* CLIENT_SUPPORT */
2760 RSP_LINE("ok", handle_ok, response_type_ok, rs_essential),
2761 RSP_LINE("error", handle_error, response_type_error, rs_essential),
2762 RSP_LINE("Valid-requests", handle_valid_requests, response_type_normal,
2764 RSP_LINE("Checked-in", handle_checked_in, response_type_normal,
2766 RSP_LINE("New-entry", handle_new_entry, response_type_normal, rs_optional),
2767 RSP_LINE("Checksum", handle_checksum, response_type_normal, rs_optional),
2768 RSP_LINE("Copy-file", handle_copy_file, response_type_normal, rs_optional),
2769 RSP_LINE("Updated", handle_updated, response_type_normal, rs_essential),
2770 RSP_LINE("Created", handle_created, response_type_normal, rs_optional),
2771 RSP_LINE("Update-existing", handle_update_existing, response_type_normal,
2773 RSP_LINE("Merged", handle_merged, response_type_normal, rs_essential),
2774 RSP_LINE("Patched", handle_patched, response_type_normal, rs_optional),
2775 RSP_LINE("Rcs-diff", handle_rcs_diff, response_type_normal, rs_optional),
2776 RSP_LINE("Mode", handle_mode, response_type_normal, rs_optional),
2777 RSP_LINE("Mod-time", handle_mod_time, response_type_normal, rs_optional),
2778 RSP_LINE("Removed", handle_removed, response_type_normal, rs_essential),
2779 RSP_LINE("Remove-entry", handle_remove_entry, response_type_normal,
2781 RSP_LINE("Set-static-directory", handle_set_static_directory,
2782 response_type_normal,
2784 RSP_LINE("Clear-static-directory", handle_clear_static_directory,
2785 response_type_normal,
2787 RSP_LINE("Set-sticky", handle_set_sticky, response_type_normal,
2789 RSP_LINE("Clear-sticky", handle_clear_sticky, response_type_normal,
2791 RSP_LINE("Template", handle_template, response_type_normal,
2793 RSP_LINE("Clear-template", handle_clear_template, response_type_normal,
2795 RSP_LINE("Notified", handle_notified, response_type_normal, rs_optional),
2796 RSP_LINE("Module-expansion", handle_module_expansion, response_type_normal,
2798 RSP_LINE("Wrapper-rcsOption", handle_wrapper_rcs_option,
2799 response_type_normal,
2801 RSP_LINE("M", handle_m, response_type_normal, rs_essential),
2802 RSP_LINE("Mbinary", handle_mbinary, response_type_normal, rs_optional),
2803 RSP_LINE("E", handle_e, response_type_normal, rs_essential),
2804 RSP_LINE("F", handle_f, response_type_normal, rs_optional),
2805 RSP_LINE("MT", handle_mt, response_type_normal, rs_optional),
2806 /* Possibly should be response_type_error. */
2807 RSP_LINE(NULL, NULL, response_type_normal, rs_essential)
2812 #endif /* CLIENT_SUPPORT or SERVER_SUPPORT */
2813 #ifdef CLIENT_SUPPORT
2818 * If LEN is 0, then send_to_server_via() computes string's length itself.
2820 * Therefore, pass the real length when transmitting data that might
2824 send_to_server_via (struct buffer *via_buffer, const char *str, size_t len)
2831 buf_output (via_buffer, str, len);
2833 /* There is no reason not to send data to the server, so do it
2834 whenever we've accumulated enough information in the buffer to
2835 make it worth sending. */
2837 if (nbytes >= 2 * BUFFER_DATA_SIZE)
2841 status = buf_send_output (via_buffer);
2843 error (1, status, "error writing to server");
2851 send_to_server (const char *str, size_t len)
2853 send_to_server_via (global_to_server, str, len);
2858 /* Read up to LEN bytes from the server. Returns actual number of
2859 bytes read, which will always be at least one; blocks if there is
2860 no data available at all. Gives a fatal error on EOF or error. */
2862 try_read_from_server( char *buf, size_t len )
2867 status = buf_read_data (global_from_server, len, &data, &nread);
2872 "end of file from server (consult above messages if any)");
2873 else if (status == -2)
2874 error (1, 0, "out of memory");
2876 error (1, status, "reading from server");
2879 memcpy (buf, data, nread);
2885 * Read LEN bytes from the server or die trying.
2888 read_from_server( char *buf, size_t len )
2893 red += try_read_from_server (buf + red, len - red);
2900 * Get some server responses and process them. Returns nonzero for
2901 * error, 0 for success. */
2903 get_server_responses( void )
2905 struct response *rs;
2911 len = read_line (&cmd);
2912 for (rs = responses; rs->name != NULL; ++rs)
2913 if (strncmp (cmd, rs->name, strlen (rs->name)) == 0)
2915 int cmdlen = strlen (rs->name);
2916 if (cmd[cmdlen] == '\0')
2918 else if (cmd[cmdlen] == ' ')
2922 * The first len characters match, but it's a different
2923 * response. e.g. the response is "oklahoma" but we
2927 (*rs->func) (cmd + cmdlen, len - cmdlen);
2930 if (rs->name == NULL)
2931 /* It's OK to print just to the first '\0'. */
2932 /* We might want to handle control characters and the like
2933 in some other way other than just sending them to stdout.
2934 One common reason for this error is if people use :ext:
2935 with a version of rsh which is doing CRLF translation or
2936 something, and so the client gets "ok^M" instead of "ok".
2937 Right now that will tend to print part of this error
2938 message over the other part of it. It seems like we could
2939 do better (either in general, by quoting or omitting all
2940 control characters, and/or specifically, by detecting the CRLF
2941 case and printing a specific error message). */
2943 "warning: unrecognized response `%s' from cvs server",
2946 } while (rs->type == response_type_normal);
2948 if (updated_fname != NULL)
2950 /* Output the previous message now. This can happen
2951 if there was no Update-existing or other such
2952 response, due to the -n global option. */
2953 cvs_output ("U ", 0);
2954 cvs_output (updated_fname, 0);
2955 cvs_output ("\n", 1);
2956 free (updated_fname);
2957 updated_fname = NULL;
2960 if (rs->type == response_type_error)
2969 /* Get the responses and then close the connection. */
2972 * Flag var; we'll set it in start_server() and not one of its
2973 * callees, such as start_rsh_server(). This means that there might
2974 * be a small window between the starting of the server and the
2975 * setting of this var, but all the code in that window shouldn't care
2976 * because it's busy checking return values to see if the server got
2977 * started successfully anyway.
2979 int server_started = 0;
2982 get_responses_and_close( void )
2984 int errs = get_server_responses ();
2987 /* The following is necessary when working with multiple cvsroots, at least
2988 * with commit. It used to be buried nicely in do_deferred_progs() before
2989 * that function was removed. I suspect it wouldn't be necessary if
2990 * call_in_directory() saved its working directory via save_cwd() before
2991 * changing its directory and restored the saved working directory via
2992 * restore_cwd() before exiting. Of course, calling CVS_CHDIR only once,
2993 * here, may be more efficient.
2995 if( toplevel_wd != NULL )
2997 if( CVS_CHDIR( toplevel_wd ) < 0 )
2998 error( 1, errno, "could not chdir to %s", toplevel_wd );
3001 if (client_prune_dirs)
3002 process_prune_candidates ();
3004 /* First we shut down GLOBAL_TO_SERVER. That tells the server that its input is
3005 * finished. It then shuts down the buffer it is sending to us, at which
3006 * point our shut down of GLOBAL_FROM_SERVER will complete.
3009 status = buf_shutdown (global_to_server);
3011 error (0, status, "shutting down buffer to server");
3012 buf_free (global_to_server);
3013 global_to_server = NULL;
3015 status = buf_shutdown (global_from_server);
3017 error (0, status, "shutting down buffer from server");
3018 buf_free (global_from_server);
3019 global_from_server = NULL;
3022 /* see if we need to sleep before returning to avoid time-stamp races */
3023 if (last_register_time)
3025 sleep_past (last_register_time);
3032 supported_request( char *name )
3036 for (rq = requests; rq->name; rq++)
3037 if (!strcmp (rq->name, name))
3038 return (rq->flags & RQ_SUPPORTED) != 0;
3039 error (1, 0, "internal error: testing support for unknown option?");
3046 #if defined (AUTH_CLIENT_SUPPORT) || defined (HAVE_KERBEROS) || defined (HAVE_GSSAPI)
3049 /* Generic function to do port number lookup tasks.
3051 * In order of precedence, will return:
3052 * getenv (envname), if defined
3053 * getservbyname (portname), if defined
3057 get_port_number (const char *envname, const char *portname, int defaultport)
3062 if (envname && (port_s = getenv (envname)))
3064 int port = atoi (port_s);
3067 error (0, 0, "%s must be a positive integer! If you", envname);
3068 error (0, 0, "are trying to force a connection via rsh, please");
3069 error (0, 0, "put \":server:\" at the beginning of your CVSROOT");
3070 error (1, 0, "variable.");
3074 else if (portname && (s = getservbyname (portname, "tcp")))
3075 return ntohs (s->s_port);
3082 /* get the port number for a client to connect to based on the port
3083 * and method of a cvsroot_t.
3085 * we do this here instead of in parse_cvsroot so that we can keep network
3086 * code confined to a localized area and also to delay the lookup until the
3087 * last possible moment so it remains possible to run cvs client commands that
3088 * skip opening connections to the server (i.e. skip network operations
3091 * and yes, I know none of the commands do that now, but here's to planning
3092 * for the future, eh? cheers.
3095 get_cvs_port_number (const cvsroot_t *root)
3098 if (root->port) return root->port;
3100 switch (root->method)
3103 case gserver_method:
3104 # endif /* HAVE_GSSAPI */
3105 # ifdef AUTH_CLIENT_SUPPORT
3106 case pserver_method:
3107 # endif /* AUTH_CLIENT_SUPPORT */
3108 # if defined (AUTH_CLIENT_SUPPORT) || defined (HAVE_GSSAPI)
3109 return get_port_number ("CVS_CLIENT_PORT", "cvspserver",
3111 # endif /* defined (AUTH_CLIENT_SUPPORT) || defined (HAVE_GSSAPI) */
3112 # ifdef HAVE_KERBEROS
3113 case kserver_method:
3114 return get_port_number ("CVS_CLIENT_PORT", "cvs", CVS_PORT);
3115 # endif /* HAVE_KERBEROS */
3118 "internal error: get_cvs_port_number called for invalid connection method (%s)",
3119 method_names[root->method]);
3128 /* get the port number for a client to connect to based on the proxy port
3132 get_proxy_port_number (const cvsroot_t *root)
3135 if (root->proxy_port) return root->proxy_port;
3137 return get_port_number ("CVS_PROXY_PORT", NULL, CVS_PROXY_PORT);
3143 make_bufs_from_fds( int tofd, int fromfd, int child_pid,
3144 struct buffer **to_server_p,
3145 struct buffer **from_server_p, int is_sock )
3148 FILE *from_server_fp;
3150 # ifdef NO_SOCKET_TO_FD
3153 assert (tofd == fromfd);
3154 *to_server_p = socket_buffer_initialize (tofd, 0,
3155 (BUFMEMERRPROC) NULL);
3156 *from_server_p = socket_buffer_initialize (tofd, 1,
3157 (BUFMEMERRPROC) NULL);
3160 # endif /* NO_SOCKET_TO_FD */
3162 /* todo: some OS's don't need these calls... */
3163 close_on_exec (tofd);
3164 close_on_exec (fromfd);
3166 /* SCO 3 and AIX have a nasty bug in the I/O libraries which precludes
3167 fdopening the same file descriptor twice, so dup it if it is the
3171 fromfd = dup (tofd);
3173 error (1, errno, "cannot dup net connection");
3176 /* These will use binary mode on systems which have it. */
3178 * Also, we know that from_server is shut down second, so we pass
3179 * child_pid in there. In theory, it should be stored in both
3180 * buffers with a ref count...
3182 to_server_fp = fdopen (tofd, FOPEN_BINARY_WRITE);
3183 if (to_server_fp == NULL)
3184 error (1, errno, "cannot fdopen %d for write", tofd);
3185 *to_server_p = stdio_buffer_initialize (to_server_fp, 0, 0,
3186 (BUFMEMERRPROC) NULL);
3188 from_server_fp = fdopen (fromfd, FOPEN_BINARY_READ);
3189 if (from_server_fp == NULL)
3190 error (1, errno, "cannot fdopen %d for read", fromfd);
3191 *from_server_p = stdio_buffer_initialize (from_server_fp, child_pid, 1,
3192 (BUFMEMERRPROC) NULL);
3195 #endif /* defined (AUTH_CLIENT_SUPPORT) || defined (HAVE_KERBEROS) || defined(HAVE_GSSAPI) */
3199 #if defined (AUTH_CLIENT_SUPPORT) || defined(HAVE_GSSAPI)
3200 /* Connect to the authenticating server.
3202 If VERIFY_ONLY is non-zero, then just verify that the password is
3203 correct and then shutdown the connection.
3205 If VERIFY_ONLY is 0, then really connect to the server.
3207 If DO_GSSAPI is non-zero, then we use GSSAPI authentication rather
3208 than the pserver password authentication.
3210 If we fail to connect or if access is denied, then die with fatal
3213 connect_to_pserver (cvsroot_t *root, struct buffer **to_server_p,
3214 struct buffer **from_server_p, int verify_only,
3218 int port_number, proxy_port_number;
3219 struct sockaddr_in client_sai;
3220 struct hostent *hostinfo;
3221 struct buffer *to_server, *from_server;
3223 sock = socket (AF_INET, SOCK_STREAM, 0);
3225 error (1, 0, "cannot create socket: %s", SOCK_STRERROR (SOCK_ERRNO));
3226 port_number = get_cvs_port_number (root);
3228 /* if we have a proxy connect to that instead */
3229 if (root->proxy_hostname)
3231 proxy_port_number = get_proxy_port_number (root);
3232 hostinfo = init_sockaddr (&client_sai, root->proxy_hostname,
3234 TRACE (1, "Connecting to %s:%d via proxy %s(%s):%d.",
3235 root->hostname, port_number, root->proxy_hostname,
3236 inet_ntoa (client_sai.sin_addr), proxy_port_number);
3240 hostinfo = init_sockaddr (&client_sai, root->hostname, port_number);
3241 TRACE (1, "Connecting to %s(%s):%d.",
3243 inet_ntoa (client_sai.sin_addr), port_number);
3246 if (connect (sock, (struct sockaddr *) &client_sai, sizeof (client_sai))
3248 error (1, 0, "connect to %s(%s):%d failed: %s",
3249 root->proxy_hostname ? root->proxy_hostname : root->hostname,
3250 inet_ntoa (client_sai.sin_addr),
3251 root->proxy_hostname ? proxy_port_number : port_number,
3252 SOCK_STRERROR (SOCK_ERRNO));
3254 make_bufs_from_fds (sock, sock, 0, &to_server, &from_server, 1);
3256 /* if we have proxy then connect to the proxy first */
3257 if (root->proxy_hostname)
3259 #define CONNECT_STRING "CONNECT %s:%d HTTP/1.0\r\n\r\n"
3260 /* Send a "CONNECT" command to proxy: */
3264 /* 4 characters for port covered by the length of %s & %d */
3265 char* write_buf = asnprintf (NULL, &count, CONNECT_STRING,
3266 root->hostname, port_number);
3267 send_to_server_via (to_server, write_buf, count);
3269 /* Wait for HTTP status code, bail out if you don't get back a 2xx
3272 read_line_via (from_server, to_server, &read_buf);
3273 sscanf (read_buf, "%s %d", write_buf, &codenum);
3275 if ((codenum / 100) != 2)
3276 error (1, 0, "proxy server %s:%d does not support http tunnelling",
3277 root->proxy_hostname, proxy_port_number);
3281 /* Skip through remaining part of MIME header, recv_line
3282 consumes the trailing \n */
3283 while (read_line_via (from_server, to_server, &read_buf) > 0)
3285 if (read_buf[0] == '\r' || read_buf[0] == 0)
3294 auth_server (root, to_server, from_server, verify_only, do_gssapi,
3301 status = buf_shutdown (to_server);
3303 error (0, status, "shutting down buffer to server");
3304 buf_free (to_server);
3307 status = buf_shutdown (from_server);
3309 error (0, status, "shutting down buffer from server");
3310 buf_free (from_server);
3313 /* Don't need to set server_started = 0 since we don't set it to 1
3314 * until returning from this call.
3319 *to_server_p = to_server;
3320 *from_server_p = from_server;
3329 auth_server (cvsroot_t *root, struct buffer *to_server,
3330 struct buffer *from_server, int verify_only, int do_gssapi,
3331 struct hostent *hostinfo)
3333 char *username = NULL; /* the username we use to connect */
3334 char no_passwd = 0; /* gets set if no password found */
3336 /* Run the authorization mini-protocol before anything else. */
3340 FILE *fp = stdio_buffer_get_file (to_server);
3341 int fd = fp ? fileno (fp) : -1;
3344 if ((fd < 0) || (fstat (fd, &s) < 0) || !S_ISSOCK(s.st_mode))
3347 "gserver currently only enabled for socket connections");
3350 if (! connect_to_gserver (root, fd, hostinfo))
3353 "authorization failed: server %s rejected access to %s",
3354 root->hostname, root->directory);
3356 # else /* ! HAVE_GSSAPI */
3358 "INTERNAL ERROR: This client does not support GSSAPI authentication");
3359 # endif /* HAVE_GSSAPI */
3361 else /* ! do_gssapi */
3363 # ifdef AUTH_CLIENT_SUPPORT
3365 char *password = NULL;
3370 begin = "BEGIN VERIFICATION REQUEST";
3371 end = "END VERIFICATION REQUEST";
3375 begin = "BEGIN AUTH REQUEST";
3376 end = "END AUTH REQUEST";
3379 /* Get the password, probably from ~/.cvspass. */
3380 password = get_cvs_password ();
3381 username = root->username ? root->username : getcaller();
3383 /* Send the empty string by default. This is so anonymous CVS
3384 access doesn't require client to have done "cvs login". */
3385 if (password == NULL)
3388 password = scramble ("");
3391 /* Announce that we're starting the authorization protocol. */
3392 send_to_server_via(to_server, begin, 0);
3393 send_to_server_via(to_server, "\012", 1);
3395 /* Send the data the server needs. */
3396 send_to_server_via(to_server, root->directory, 0);
3397 send_to_server_via(to_server, "\012", 1);
3398 send_to_server_via(to_server, username, 0);
3399 send_to_server_via(to_server, "\012", 1);
3400 send_to_server_via(to_server, password, 0);
3401 send_to_server_via(to_server, "\012", 1);
3403 /* Announce that we're ending the authorization protocol. */
3404 send_to_server_via(to_server, end, 0);
3405 send_to_server_via(to_server, "\012", 1);
3408 memset (password, 0, strlen (password));
3409 # else /* ! AUTH_CLIENT_SUPPORT */
3410 error (1, 0, "INTERNAL ERROR: This client does not support pserver authentication");
3411 # endif /* AUTH_CLIENT_SUPPORT */
3412 } /* if (do_gssapi) */
3417 /* Loop, getting responses from the server. */
3420 read_line_via (from_server, to_server, &read_buf);
3422 if (strcmp (read_buf, "I HATE YOU") == 0)
3424 /* Authorization not granted.
3426 * This is a little confusing since we can reach this while
3427 * loop in GSSAPI mode, but if GSSAPI authentication failed,
3428 * we already jumped to the rejected label (there is no case
3429 * where the connect_to_gserver function can return 1 and we
3430 * will not receive "I LOVE YOU" from the server, barring
3431 * broken connections and garbled messages, of course). The
3432 * GSSAPI case is also the case where username can be NULL
3433 * since username is initialized in the !gssapi section.
3435 * i.e. This is a pserver specific error message and should be
3436 * since GSSAPI doesn't use username.
3439 "authorization failed: server %s rejected access to %s for user %s",
3440 root->hostname, root->directory,
3441 username ? username : "(null)");
3443 /* Output a special error message if authentication was attempted
3444 with no password -- the user should be made aware that they may
3445 have missed a step. */
3449 "used empty password; try \"cvs login\" with a real password");
3451 exit (EXIT_FAILURE);
3453 else if (strncmp (read_buf, "E ", 2) == 0)
3455 fprintf (stderr, "%s\n", read_buf + 2);
3457 /* Continue with the authentication protocol. */
3459 else if (strncmp (read_buf, "error ", 6) == 0)
3463 /* First skip the code. */
3465 while (*p != ' ' && *p != '\0')
3468 /* Skip the space that follows the code. */
3472 /* Now output the text. */
3473 fprintf (stderr, "%s\n", p);
3474 exit (EXIT_FAILURE);
3476 else if (strcmp (read_buf, "I LOVE YOU") == 0)
3484 "unrecognized auth response from %s: %s",
3485 root->hostname, read_buf);
3491 #endif /* defined (AUTH_CLIENT_SUPPORT) || defined(HAVE_GSSAPI) */
3495 #ifdef CLIENT_SUPPORT
3497 * Connect to a forked server process.
3500 connect_to_forked_server (struct buffer **to_server_p,
3501 struct buffer **from_server_p)
3506 /* This is pretty simple. All we need to do is choose the correct
3507 cvs binary and call piped_child. */
3511 command[0] = getenv ("CVS_SERVER");
3513 # ifdef SERVER_SUPPORT
3515 * I'm casting out the const below because I know that piped_child, the
3516 * only function we pass COMMAND to, accepts COMMAND as a
3517 * (char *const *) and won't alter it, and we don't alter it in this
3518 * function. This is yucky, there should be a way to declare COMMAND
3519 * such that this casting isn't needed, but I don't know how. If I
3520 * declare it as (const char *command[]), the compiler complains about
3521 * an incompatible arg 1 being passed to piped_child and if I declare
3522 * it as (char *const command[3]), then the compiler complains when I
3523 * assign values to command[i].
3525 command[0] = (char *)program_path;
3526 # else /* SERVER_SUPPORT */
3528 error( 0, 0, "You must set the CVS_SERVER environment variable when" );
3529 error( 0, 0, "using the :fork: access method." );
3530 error( 1, 0, "This CVS was not compiled with server support." );
3532 # endif /* SERVER_SUPPORT */
3534 command[1] = "server";
3537 TRACE (TRACE_FUNCTION, "Forking server: %s %s\n",
3538 command[0] ? command[0] : "(null)", command[1]);
3540 child_pid = piped_child (command, &tofd, &fromfd);
3542 error (1, 0, "could not fork server process");
3544 make_bufs_from_fds (tofd, fromfd, child_pid, to_server_p, from_server_p, 0);
3546 #endif /* CLIENT_SUPPORT */
3551 send_variable_proc (Node *node, void *closure)
3553 send_to_server ("Set ", 0);
3554 send_to_server (node->key, 0);
3555 send_to_server ("=", 1);
3556 send_to_server (node->data, 0);
3557 send_to_server ("\012", 1);
3563 /* Contact the server. */
3569 /* Clear our static variables for this invocation. */
3570 if (toplevel_repos != NULL)
3571 free (toplevel_repos);
3572 toplevel_repos = NULL;
3574 /* Note that generally speaking we do *not* fall back to a different
3575 way of connecting if the first one does not work. This is slow
3576 (*really* slow on a 14.4kbps link); the clean way to have a CVS
3577 which supports several ways of connecting is with access methods. */
3579 switch (current_parsed_root->method)
3582 #ifdef AUTH_CLIENT_SUPPORT
3583 case pserver_method:
3584 /* Toss the return value. It will die with an error message if
3585 * anything goes wrong anyway.
3587 connect_to_pserver (current_parsed_root, &global_to_server,
3588 &global_from_server, 0, 0);
3590 #endif /* AUTH_CLIENT_SUPPORT */
3593 case kserver_method:
3594 start_kerberos4_server (current_parsed_root, &global_to_server,
3595 &global_from_server);
3597 #endif /* HAVE_KERBEROS */
3600 case gserver_method:
3601 /* GSSAPI authentication is handled by the pserver. */
3602 connect_to_pserver (current_parsed_root, &global_to_server,
3603 &global_from_server, 0, 1);
3605 #endif /* HAVE_GSSAPI */
3608 #ifdef NO_EXT_METHOD
3609 error (0, 0, ":ext: method not supported by this port of CVS");
3610 error (1, 0, "try :server: instead");
3611 #else /* ! NO_EXT_METHOD */
3612 start_rsh_server (current_parsed_root, &global_to_server,
3613 &global_from_server);
3614 #endif /* NO_EXT_METHOD */
3621 START_SERVER (&tofd, &fromfd, getcaller (),
3622 current_parsed_root->username,
3623 current_parsed_root->hostname,
3624 current_parsed_root->directory);
3625 # ifdef START_SERVER_RETURNS_SOCKET
3626 make_bufs_from_fds (tofd, fromfd, 0, &global_to_server,
3627 &global_from_server, 1);
3628 # else /* ! START_SERVER_RETURNS_SOCKET */
3629 make_bufs_from_fds (tofd, fromfd, 0, &global_to_server,
3630 &global_from_server, 0);
3631 # endif /* START_SERVER_RETURNS_SOCKET */
3633 #else /* ! START_SERVER */
3634 /* FIXME: It should be possible to implement this portably,
3635 like pserver, which would get rid of the duplicated code
3636 in {vms,windows-NT,...}/startserver.c. */
3638 "the :server: access method is not supported by this port of CVS");
3639 #endif /* START_SERVER */
3643 connect_to_forked_server (&global_to_server, &global_from_server);
3648 "(start_server internal error): unknown access method");
3652 /* "Hi, I'm Darlene and I'll be your server tonight..." */
3655 setup_logfiles(&global_to_server, &global_from_server);
3657 /* Clear static variables. */
3658 if (toplevel_repos != NULL)
3659 free (toplevel_repos);
3660 toplevel_repos = NULL;
3661 if (last_repos != NULL)
3664 if (last_update_dir != NULL)
3665 free (last_update_dir);
3666 last_update_dir = NULL;
3667 stored_checksum_valid = 0;
3668 if (stored_mode != NULL)
3674 rootless = (strcmp (cvs_cmd_name, "init") == 0);
3677 send_to_server ("Root ", 0);
3678 send_to_server (current_parsed_root->directory, 0);
3679 send_to_server ("\012", 1);
3683 struct response *rs;
3685 send_to_server ("Valid-responses", 0);
3687 for (rs = responses; rs->name != NULL; ++rs)
3689 send_to_server (" ", 0);
3690 send_to_server (rs->name, 0);
3692 send_to_server ("\012", 1);
3694 send_to_server ("valid-requests\012", 0);
3696 if (get_server_responses ())
3697 exit (EXIT_FAILURE);
3700 * Now handle global options.
3702 * -H, -f, -d, -e should be handled OK locally.
3704 * -b we ignore (treating it as a server installation issue).
3705 * FIXME: should be an error message.
3707 * -v we print local version info; FIXME: Add a protocol request to get
3708 * the version from the server so we can print that too.
3710 * -l -t -r -w -q -n and -Q need to go to the server.
3714 int have_global = supported_request ("Global_option");
3720 send_to_server ("Global_option -n\012", 0);
3724 "This server does not support the global -n option.");
3730 send_to_server ("Global_option -q\012", 0);
3734 "This server does not support the global -q option.");
3740 send_to_server ("Global_option -Q\012", 0);
3744 "This server does not support the global -Q option.");
3750 send_to_server ("Global_option -r\012", 0);
3754 "This server does not support the global -r option.");
3761 while (count--) send_to_server ("Global_option -t\012", 0);
3765 "This server does not support the global -t option.");
3769 /* Find out about server-side cvswrappers. An extra network
3770 turnaround for cvs import seems to be unavoidable, unless we
3771 want to add some kind of client-side place to configure which
3772 filenames imply binary. For cvs add, we could avoid the
3773 problem by keeping a copy of the wrappers in CVSADM (the main
3774 reason to bother would be so we could make add work without
3775 contacting the server, I suspect). */
3777 if ((strcmp (cvs_cmd_name, "import") == 0)
3778 || (strcmp (cvs_cmd_name, "add") == 0))
3780 if (supported_request ("wrapper-sendme-rcsOptions"))
3783 send_to_server ("wrapper-sendme-rcsOptions\012", 0);
3784 err = get_server_responses ();
3786 error (err, 0, "error reading from server");
3790 if (cvsencrypt && !rootless)
3793 /* Turn on encryption before turning on compression. We do
3794 not want to try to compress the encrypted stream. Instead,
3795 we want to encrypt the compressed stream. If we can't turn
3796 on encryption, bomb out; don't let the user think the data
3797 is being encrypted when it is not. */
3798 #ifdef HAVE_KERBEROS
3799 if (current_parsed_root->method == kserver_method)
3801 if (! supported_request ("Kerberos-encrypt"))
3802 error (1, 0, "This server does not support encryption");
3803 send_to_server ("Kerberos-encrypt\012", 0);
3804 initialize_kerberos4_encryption_buffers (&global_to_server,
3805 &global_from_server);
3808 #endif /* HAVE_KERBEROS */
3810 if (current_parsed_root->method == gserver_method)
3812 if (! supported_request ("Gssapi-encrypt"))
3813 error (1, 0, "This server does not support encryption");
3814 send_to_server ("Gssapi-encrypt\012", 0);
3815 initialize_gssapi_buffers(&global_to_server, &global_from_server);
3816 cvs_gssapi_encrypt = 1;
3819 #endif /* HAVE_GSSAPI */
3821 "Encryption is only supported when using GSSAPI or Kerberos");
3822 #else /* ! ENCRYPTION */
3823 error (1, 0, "This client does not support encryption");
3824 #endif /* ! ENCRYPTION */
3827 if (gzip_level && !rootless)
3829 if (supported_request ("Gzip-stream"))
3831 char gzip_level_buf[5];
3832 send_to_server ("Gzip-stream ", 0);
3833 sprintf (gzip_level_buf, "%d", gzip_level);
3834 send_to_server (gzip_level_buf, 0);
3835 send_to_server ("\012", 1);
3837 /* All further communication with the server will be
3840 global_to_server = compress_buffer_initialize (global_to_server, 0,
3842 global_from_server = compress_buffer_initialize (global_from_server,
3846 #ifndef NO_CLIENT_GZIP_PROCESS
3847 else if (supported_request ("gzip-file-contents"))
3849 char gzip_level_buf[5];
3850 send_to_server ("gzip-file-contents ", 0);
3851 sprintf (gzip_level_buf, "%d", gzip_level);
3852 send_to_server (gzip_level_buf, 0);
3854 send_to_server ("\012", 1);
3856 file_gzip_level = gzip_level;
3861 fprintf (stderr, "server doesn't support gzip-file-contents\n");
3862 /* Setting gzip_level to 0 prevents us from giving the
3863 error twice if update has to contact the server again
3864 to fetch unpatchable files. */
3869 if (cvsauthenticate && ! cvsencrypt && !rootless)
3871 /* Turn on authentication after turning on compression, so
3872 that we can compress the authentication information. We
3873 assume that encrypted data is always authenticated--the
3874 ability to decrypt the data stream is itself a form of
3877 if (current_parsed_root->method == gserver_method)
3879 if (! supported_request ("Gssapi-authenticate"))
3881 "This server does not support stream authentication");
3882 send_to_server ("Gssapi-authenticate\012", 0);
3883 initialize_gssapi_buffers(&global_to_server, &global_from_server);
3887 error (1, 0, "Stream authentication is only supported when using GSSAPI");
3888 #else /* ! HAVE_GSSAPI */
3889 error (1, 0, "This client does not support stream authentication");
3890 #endif /* ! HAVE_GSSAPI */
3893 /* If "Set" is not supported, just silently fail to send the variables.
3894 Users with an old server should get a useful error message when it
3895 fails to recognize the ${=foo} syntax. This way if someone uses
3896 several servers, some of which are new and some old, they can still
3897 set user variables in their .cvsrc without trouble. */
3898 if (supported_request ("Set"))
3899 walklist (variable_list, send_variable_proc, NULL);
3904 /* Send an argument STRING. */
3906 send_arg (char *string)
3911 send_to_server ("Argument ", 0);
3917 send_to_server ("\012Argumentx ", 0);
3922 send_to_server (buf, 1);
3926 send_to_server ("\012", 1);
3931 /* VERS->OPTIONS specifies whether the file is binary or not. NOTE: BEFORE
3932 using any other fields of the struct vers, we would need to fix
3933 client_process_import_file to set them up. */
3935 send_modified (const char *file, const char *short_pathname, Vers_TS *vers)
3937 /* File was modified, send it. */
3945 TRACE (1, "Sending file `%s' to server", file);
3947 /* Don't think we can assume fstat exists. */
3948 if (CVS_STAT (file, &sb) < 0)
3949 error (1, errno, "reading %s", short_pathname);
3951 mode_string = mode_to_string (sb.st_mode);
3953 /* Beware: on systems using CRLF line termination conventions,
3954 the read and write functions will convert CRLF to LF, so the
3955 number of characters read is not the same as sb.st_size. Text
3956 files should always be transmitted using the LF convention, so
3957 we don't want to disable this conversion. */
3958 bufsize = sb.st_size;
3959 buf = xmalloc (bufsize);
3961 /* Is the file marked as containing binary data by the "-kb" flag?
3962 If so, make sure to open it in binary mode: */
3964 if (vers && vers->options)
3965 bin = !(strcmp (vers->options, "-kb"));
3969 #ifdef BROKEN_READWRITE_CONVERSION
3972 /* If only stdio, not open/write/etc., do text/binary
3973 conversion, use convert_file which can compensate
3974 (FIXME: we could just use stdio instead which would
3975 avoid the whole problem). */
3976 char tfile[1024]; strcpy(tfile, file); strcat(tfile, ".CVSBFCTMP");
3977 convert_file (file, O_RDONLY,
3978 tfile, O_WRONLY | O_CREAT | O_TRUNC | OPEN_BINARY);
3979 fd = CVS_OPEN (tfile, O_RDONLY | OPEN_BINARY);
3981 error (1, errno, "reading %s", short_pathname);
3984 fd = CVS_OPEN (file, O_RDONLY | OPEN_BINARY);
3986 fd = CVS_OPEN (file, O_RDONLY | (bin ? OPEN_BINARY : 0));
3990 error (1, errno, "reading %s", short_pathname);
3992 if (file_gzip_level && sb.st_size > 100)
3996 if (read_and_gzip (fd, short_pathname, (unsigned char **)&buf,
3999 error (1, 0, "aborting due to compression error");
4002 error (0, errno, "warning: can't close %s", short_pathname);
4007 send_to_server ("Modified ", 0);
4008 send_to_server (file, 0);
4009 send_to_server ("\012", 1);
4010 send_to_server (mode_string, 0);
4011 send_to_server ("\012z", 2);
4012 sprintf (tmp, "%lu\n", (unsigned long) newsize);
4013 send_to_server (tmp, 0);
4015 send_to_server (buf, newsize);
4026 /* FIXME: This is gross. It assumes that we might read
4027 less than st_size bytes (true on NT), but not more.
4028 Instead of this we should just be reading a block of
4029 data (e.g. 8192 bytes), writing it to the network, and
4031 while ((len = read (fd, bufp, (buf + sb.st_size) - bufp)) > 0)
4035 error (1, errno, "reading %s", short_pathname);
4037 newsize = bufp - buf;
4040 error (0, errno, "warning: can't close %s", short_pathname);
4045 send_to_server ("Modified ", 0);
4046 send_to_server (file, 0);
4047 send_to_server ("\012", 1);
4048 send_to_server (mode_string, 0);
4049 send_to_server ("\012", 1);
4050 sprintf (tmp, "%lu\012", (unsigned long) newsize);
4051 send_to_server (tmp, 0);
4053 #ifdef BROKEN_READWRITE_CONVERSION
4056 char tfile[1024]; strcpy(tfile, file); strcat(tfile, ".CVSBFCTMP");
4057 if (CVS_UNLINK (tfile) < 0)
4058 error (0, errno, "warning: can't remove temp file %s", tfile);
4063 * Note that this only ends with a newline if the file ended with
4067 send_to_server (buf, newsize);
4075 /* The address of an instance of this structure is passed to
4076 send_fileproc, send_filesdoneproc, and send_direntproc, as the
4077 callerdat parameter. */
4080 /* Each of the following flags are zero for clear or nonzero for set. */
4084 int backup_modified;
4087 /* Deal with one file. */
4089 send_fileproc (void *callerdat, struct file_info *finfo)
4091 struct send_data *args = callerdat;
4093 struct file_info xfinfo;
4094 /* File name to actually use. Might differ in case from
4096 const char *filename;
4098 send_a_repository ("", finfo->repository, finfo->update_dir);
4101 xfinfo.repository = NULL;
4103 vers = Version_TS (&xfinfo, NULL, NULL, NULL, 0, 0);
4105 if (vers->entdata != NULL)
4106 filename = vers->entdata->user;
4108 filename = finfo->file;
4110 if (vers->vn_user != NULL)
4112 /* The Entries request. */
4113 send_to_server ("Entry /", 0);
4114 send_to_server (filename, 0);
4115 send_to_server ("/", 0);
4116 send_to_server (vers->vn_user, 0);
4117 send_to_server ("/", 0);
4118 if (vers->ts_conflict != NULL)
4120 if (vers->ts_user != NULL &&
4121 strcmp (vers->ts_conflict, vers->ts_user) == 0)
4122 send_to_server ("+=", 0);
4124 send_to_server ("+modified", 0);
4126 send_to_server ("/", 0);
4127 send_to_server (vers->entdata != NULL
4128 ? vers->entdata->options
4131 send_to_server ("/", 0);
4132 if (vers->entdata != NULL && vers->entdata->tag)
4134 send_to_server ("T", 0);
4135 send_to_server (vers->entdata->tag, 0);
4137 else if (vers->entdata != NULL && vers->entdata->date)
4139 send_to_server ("D", 0);
4140 send_to_server (vers->entdata->date, 0);
4142 send_to_server ("\012", 1);
4146 /* It seems a little silly to re-read this on each file, but
4147 send_dirent_proc doesn't get called if filenames are specified
4148 explicitly on the command line. */
4149 wrap_add_file (CVSDOTWRAPPER, 1);
4151 if (wrap_name_has (filename, WRAP_RCSOPTION))
4153 /* No "Entry", but the wrappers did give us a kopt so we better
4154 send it with "Kopt". As far as I know this only happens
4155 for "cvs add". Question: is there any reason why checking
4156 for options from wrappers isn't done in Version_TS?
4158 Note: it might have been better to just remember all the
4159 kopts on the client side, rather than send them to the server,
4160 and have it send us back the same kopts. But that seemed like
4161 a bigger change than I had in mind making now. */
4163 if (supported_request ("Kopt"))
4167 send_to_server ("Kopt ", 0);
4168 opt = wrap_rcsoption (filename, 1);
4169 send_to_server (opt, 0);
4170 send_to_server ("\012", 1);
4175 warning: ignoring -k options due to server limitations");
4179 if (vers->ts_user == NULL)
4182 * Do we want to print "file was lost" like normal CVS?
4183 * Would it always be appropriate?
4185 /* File no longer exists. Don't do anything, missing files
4188 else if (vers->ts_rcs == NULL
4190 || strcmp (vers->ts_user, vers->ts_rcs) != 0)
4192 if (args->no_contents
4193 && supported_request ("Is-modified"))
4195 send_to_server ("Is-modified ", 0);
4196 send_to_server (filename, 0);
4197 send_to_server ("\012", 1);
4200 send_modified (filename, finfo->fullname, vers);
4202 if (args->backup_modified)
4205 bakname = backup_file (filename, vers->vn_user);
4206 /* This behavior is sufficiently unexpected to
4207 justify overinformativeness, I think. */
4209 printf ("(Locally modified %s moved to %s)\n",
4216 send_to_server ("Unchanged ", 0);
4217 send_to_server (filename, 0);
4218 send_to_server ("\012", 1);
4221 /* if this directory has an ignore list, add this file to it */
4228 p->key = xstrdup (finfo->file);
4229 (void) addnode (ignlist, p);
4232 freevers_ts (&vers);
4239 send_ignproc (const char *file, const char *dir)
4241 if (ign_inhibit_server || !supported_request ("Questionable"))
4244 (void) printf ("? %s/%s\n", dir, file);
4246 (void) printf ("? %s\n", file);
4250 send_to_server ("Questionable ", 0);
4251 send_to_server (file, 0);
4252 send_to_server ("\012", 1);
4259 send_filesdoneproc (void *callerdat, int err, const char *repository,
4260 const char *update_dir, List *entries)
4262 /* if this directory has an ignore list, process it then free it */
4265 ignore_files (ignlist, entries, update_dir, send_ignproc);
4275 * send_dirent_proc () is called back by the recursion processor before a
4276 * sub-directory is processed for update.
4277 * A return code of 0 indicates the directory should be
4278 * processed by the recursion code. A return of non-zero indicates the
4279 * recursion code should skip this directory.
4283 send_dirent_proc (void *callerdat, const char *dir, const char *repository,
4284 const char *update_dir, List *entries)
4286 struct send_data *args = (struct send_data *) callerdat;
4290 if (ignore_directory (update_dir))
4292 /* print the warm fuzzy message */
4294 error (0, 0, "Ignoring %s", update_dir);
4299 * If the directory does not exist yet (e.g. "cvs update -d foo"),
4300 * no need to send any files from it. If the directory does not
4301 * have a CVS directory, then we pretend that it does not exist.
4302 * Otherwise, we will fail when trying to open the Entries file.
4303 * This case will happen when checking out a module defined as
4306 cvsadm_name = xmalloc (strlen (dir) + sizeof (CVSADM) + 10);
4307 sprintf (cvsadm_name, "%s/%s", dir, CVSADM);
4308 dir_exists = isdir (cvsadm_name);
4312 * If there is an empty directory (e.g. we are doing `cvs add' on a
4313 * newly-created directory), the server still needs to know about it.
4319 * Get the repository from a CVS/Repository file whenever possible.
4320 * The repository variable is wrong if the names in the local
4321 * directory don't match the names in the repository.
4323 char *repos = Name_Repository (dir, update_dir);
4324 send_a_repository (dir, repos, update_dir);
4327 /* initialize the ignore list for this directory */
4328 ignlist = getlist ();
4332 /* It doesn't make sense to send a non-existent directory,
4333 because there is no way to get the correct value for
4334 the repository (I suppose maybe via the expand-modules
4335 request). In the case where the "obvious" choice for
4336 repository is correct, the server can figure out whether
4337 to recreate the directory; in the case where it is wrong
4338 (that is, does not match what modules give us), we might as
4339 well just fail to recreate it.
4341 Checking for noexec is a kludge for "cvs -n add dir". */
4342 /* Don't send a non-existent directory unless we are building
4343 new directories (build_dirs is true). Otherwise, CVS may
4344 see a D line in an Entries file, and recreate a directory
4345 which the user removed by hand. */
4346 if (args->build_dirs && noexec)
4347 send_a_repository (dir, repository, update_dir);
4350 return dir_exists ? R_PROCESS : R_SKIP_ALL;
4356 * send_dirleave_proc () is called back by the recursion code upon leaving
4357 * a directory. All it does is delete the ignore list if it hasn't already
4358 * been done (by send_filesdone_proc).
4362 send_dirleave_proc (void *callerdat, const char *dir, int err,
4363 const char *update_dir, List *entries )
4366 /* Delete the ignore list if it hasn't already been done. */
4373 * Send each option in a string to the server, one by one.
4374 * This assumes that the options are separated by spaces, for example
4375 * STRING might be "--foo -C5 -y".
4379 send_option_string( char *string )
4384 copy = xstrdup (string);
4391 for (s = p; *s != ' ' && *s != '\0'; s++)
4406 /* Send the names of all the argument files to the server. */
4408 send_file_names (int argc, char **argv, unsigned int flags)
4412 /* The fact that we do this here as well as start_recursion is a bit
4413 of a performance hit. Perhaps worth cleaning up someday. */
4414 if (flags & SEND_EXPAND_WILD)
4415 expand_wild (argc, argv, &argc, &argv);
4417 for (i = 0; i < argc; ++i)
4421 #ifdef FILENAMES_CASE_INSENSITIVE
4423 #endif /* FILENAMES_CASE_INSENSITIVE */
4425 if (arg_should_not_be_sent_to_server (argv[i]))
4428 #ifdef FILENAMES_CASE_INSENSITIVE
4429 /* We want to send the path as it appears in the
4430 CVS/Entries files. We put this inside an ifdef
4431 to avoid doing all these system calls in
4432 cases where fncmp is just strcmp anyway. */
4433 /* The isdir (CVSADM) check could more gracefully be replaced
4434 with a way of having Entries_Open report back the
4435 error to us and letting us ignore existence_error.
4439 size_t line_len = 0;
4441 struct saved_cwd sdir;
4443 /* Split the argument onto the stack. */
4445 r = xstrdup (argv[i]);
4446 /* It's okay to discard the const from the last_component return
4447 * below since we know we passed in an arg that was not const.
4449 while ((q = (char *)last_component (r)) != r)
4451 push (stack, xstrdup (q));
4456 /* Normalize the path into outstr. */
4458 while (q = pop (stack))
4465 /* Note that if we are adding a directory,
4466 the following will read the entry
4467 that we just wrote there, that is, we
4468 will get the case specified on the
4469 command line, not the case of the
4470 directory in the filesystem. This
4471 is correct behavior. */
4472 entries = Entries_Open (0, NULL);
4473 node = findnode_fn (entries, q);
4476 /* Add the slash unless this is our first element. */
4478 xrealloc_and_strcat (&line, &line_len, "/");
4479 xrealloc_and_strcat (&line, &line_len, node->key);
4482 Entries_Close (entries);
4485 /* If node is still NULL then we either didn't find CVSADM or
4486 * we didn't find an entry there.
4490 /* Add the slash unless this is our first element. */
4492 xrealloc_and_strcat (&line, &line_len, "/");
4493 xrealloc_and_strcat (&line, &line_len, q);
4497 /* And descend the tree. */
4502 restore_cwd (&sdir, NULL);
4505 /* Now put everything we didn't find entries for back on. */
4506 while (q = pop (stack))
4509 xrealloc_and_strcat (&line, &line_len, "/");
4510 xrealloc_and_strcat (&line, &line_len, q);
4518 #else /* !FILENAMES_CASE_INSENSITIVE */
4520 #endif /* FILENAMES_CASE_INSENSITIVE */
4522 send_to_server ("Argument ", 0);
4528 send_to_server ("\012Argumentx ", 0);
4530 else if (ISSLASH (*p))
4533 send_to_server (buf, 1);
4538 send_to_server (buf, 1);
4542 send_to_server ("\012", 1);
4543 #ifdef FILENAMES_CASE_INSENSITIVE
4545 #endif /* FILENAMES_CASE_INSENSITIVE */
4548 if (flags & SEND_EXPAND_WILD)
4551 for (i = 0; i < argc; ++i)
4559 /* Calculate and send max-dotdot to the server */
4561 send_max_dotdot (argc, argv)
4569 /* Send Max-dotdot if needed. */
4570 for (i = 0; i < argc; ++i)
4572 level = pathname_levels (argv[i]);
4575 if (uppaths == NULL) uppaths = getlist();
4576 push_string (uppaths, xstrdup (argv[i]));
4578 if (level > max_level)
4584 if (supported_request ("Max-dotdot"))
4587 sprintf (buf, "%d", max_level);
4589 send_to_server ("Max-dotdot ", 0);
4590 send_to_server (buf, 0);
4591 send_to_server ("\012", 1);
4596 "backreference in path (`..') not supported by old (pre-Max-dotdot) servers");
4603 /* Send Repository, Modified and Entry. argc and argv contain only
4604 the files to operate on (or empty for everything), not options.
4605 local is nonzero if we should not recurse (-l option). flags &
4606 SEND_BUILD_DIRS is nonzero if nonexistent directories should be
4607 sent. flags & SEND_FORCE is nonzero if we should send unmodified
4608 files to the server as though they were modified. flags &
4609 SEND_NO_CONTENTS means that this command only needs to know
4610 _whether_ a file is modified, not the contents. Also sends Argument
4611 lines for argc and argv, so should be called after options are sent. */
4613 send_files (int argc, char **argv, int local, int aflag, unsigned int flags)
4615 struct send_data args;
4618 send_max_dotdot (argc, argv);
4621 * aflag controls whether the tag/date is copied into the vers_ts.
4622 * But we don't actually use it, so I don't think it matters what we pass
4625 args.build_dirs = flags & SEND_BUILD_DIRS;
4626 args.force = flags & SEND_FORCE;
4627 args.no_contents = flags & SEND_NO_CONTENTS;
4628 args.backup_modified = flags & BACKUP_MODIFIED_FILES;
4629 err = start_recursion
4630 (send_fileproc, send_filesdoneproc, send_dirent_proc,
4631 send_dirleave_proc, &args, argc, argv, local, W_LOCAL, aflag,
4632 CVS_LOCK_NONE, NULL, 0, NULL);
4634 exit (EXIT_FAILURE);
4635 if (toplevel_repos == NULL)
4637 * This happens if we are not processing any files,
4638 * or for checkouts in directories without any existing stuff
4639 * checked out. The following assignment is correct for the
4640 * latter case; I don't think toplevel_repos matters for the
4643 toplevel_repos = xstrdup (current_parsed_root->directory);
4644 send_repository ("", toplevel_repos, ".");
4650 client_import_setup (char *repository)
4652 if (toplevel_repos == NULL) /* should always be true */
4653 send_a_repository ("", repository, "");
4659 * Process the argument import file.
4662 client_process_import_file (char *message, char *vfile, char *vtag, int targc,
4663 char *targv[], char *repository,
4664 int all_files_binary,
4665 int modtime /* Nonzero for "import -d". */ )
4671 assert (toplevel_repos != NULL);
4673 if (strncmp (repository, toplevel_repos, strlen (toplevel_repos)) != 0)
4675 "internal error: pathname `%s' doesn't specify file in `%s'",
4676 repository, toplevel_repos);
4678 if (strcmp (repository, toplevel_repos) == 0)
4681 fullname = xstrdup (vfile);
4685 update_dir = repository + strlen (toplevel_repos) + 1;
4687 fullname = xmalloc (strlen (vfile) + strlen (update_dir) + 10);
4688 strcpy (fullname, update_dir);
4689 strcat (fullname, "/");
4690 strcat (fullname, vfile);
4693 send_a_repository ("", repository, update_dir);
4694 if (all_files_binary)
4696 vers.options = xmalloc (4); /* strlen("-kb") + 1 */
4697 strcpy (vers.options, "-kb");
4701 vers.options = wrap_rcsoption (vfile, 1);
4703 if (vers.options != NULL)
4705 if (supported_request ("Kopt"))
4707 send_to_server ("Kopt ", 0);
4708 send_to_server (vers.options, 0);
4709 send_to_server ("\012", 1);
4713 "warning: ignoring -k options due to server limitations");
4717 if (supported_request ("Checkin-time"))
4721 char netdate[MAXDATELEN];
4723 if (CVS_STAT (vfile, &sb) < 0)
4724 error (1, errno, "cannot stat %s", fullname);
4725 rcsdate = date_from_time_t (sb.st_mtime);
4726 date_to_internet (netdate, rcsdate);
4729 send_to_server ("Checkin-time ", 0);
4730 send_to_server (netdate, 0);
4731 send_to_server ("\012", 1);
4735 "warning: ignoring -d option due to server limitations");
4737 send_modified (vfile, fullname, &vers);
4738 if (vers.options != NULL)
4739 free (vers.options);
4747 client_import_done (void)
4749 if (toplevel_repos == NULL)
4751 * This happens if we are not processing any files,
4752 * or for checkouts in directories without any existing stuff
4753 * checked out. The following assignment is correct for the
4754 * latter case; I don't think toplevel_repos matters for the
4757 /* FIXME: "can't happen" now that we call client_import_setup
4758 at the beginning. */
4759 toplevel_repos = xstrdup (current_parsed_root->directory);
4760 send_repository ("", toplevel_repos, ".");
4766 notified_a_file (char *data, List *ent_list, char *short_pathname,
4771 size_t line_len = 8192;
4772 char *line = xmalloc (line_len);
4778 fp = open_file (CVSADM_NOTIFY, "r");
4779 if (getline (&line, &line_len, fp) < 0)
4782 error (0, 0, "cannot read %s: end of file", CVSADM_NOTIFY);
4784 error (0, errno, "cannot read %s", CVSADM_NOTIFY);
4787 cp = strchr (line, '\t');
4790 error (0, 0, "malformed %s file", CVSADM_NOTIFY);
4794 if (strcmp (filename, line + 1) != 0)
4796 error (0, 0, "protocol error: notified %s, expected %s", filename,
4800 if (getline (&line, &line_len, fp) < 0)
4805 if (fclose (fp) < 0)
4806 error (0, errno, "cannot close %s", CVSADM_NOTIFY);
4807 if ( CVS_UNLINK (CVSADM_NOTIFY) < 0)
4808 error (0, errno, "cannot remove %s", CVSADM_NOTIFY);
4813 error (0, errno, "cannot read %s", CVSADM_NOTIFY);
4817 newf = open_file (CVSADM_NOTIFYTMP, "w");
4818 if (fputs (line, newf) < 0)
4820 error (0, errno, "cannot write %s", CVSADM_NOTIFYTMP);
4823 while ((nread = fread (line, 1, line_len, fp)) > 0)
4826 while ((nwritten = fwrite (p, 1, nread, newf)) > 0)
4833 error (0, errno, "cannot write %s", CVSADM_NOTIFYTMP);
4839 error (0, errno, "cannot read %s", CVSADM_NOTIFY);
4842 if (fclose (newf) < 0)
4844 error (0, errno, "cannot close %s", CVSADM_NOTIFYTMP);
4848 if (fclose (fp) < 0)
4850 error (0, errno, "cannot close %s", CVSADM_NOTIFY);
4855 /* In this case, we want rename_file() to ignore noexec. */
4856 int saved_noexec = noexec;
4858 rename_file (CVSADM_NOTIFYTMP, CVSADM_NOTIFY);
4859 noexec = saved_noexec;
4864 (void)fclose (newf);
4873 handle_notified (char *args, int len)
4875 call_in_directory (args, notified_a_file, NULL);
4881 client_notify (const char *repository, const char *update_dir,
4882 const char *filename, int notif_type, const char *val)
4886 send_a_repository ("", repository, update_dir);
4887 send_to_server ("Notify ", 0);
4888 send_to_server (filename, 0);
4889 send_to_server ("\012", 1);
4890 buf[0] = notif_type;
4892 send_to_server (buf, 1);
4893 send_to_server ("\t", 1);
4894 send_to_server (val, 0);
4900 * Send an option with an argument, dealing correctly with newlines in
4901 * the argument. If ARG is NULL, forget the whole thing.
4904 option_with_arg (char *option, char *arg)
4909 send_to_server ("Argument ", 0);
4910 send_to_server (option, 0);
4911 send_to_server ("\012", 1);
4918 /* Send a date to the server. The input DATE is in RCS format.
4919 The time will be GMT.
4921 We then convert that to the format required in the protocol
4922 (including the "-D" option) and send it. According to
4923 cvsclient.texi, RFC 822/1123 format is preferred. */
4925 client_senddate (const char *date)
4927 char buf[MAXDATELEN];
4929 date_to_internet (buf, (char *)date);
4930 option_with_arg ("-D", buf);
4936 send_init_command (void)
4938 /* This is here because we need the current_parsed_root->directory variable. */
4939 send_to_server ("init ", 0);
4940 send_to_server (current_parsed_root->directory, 0);
4941 send_to_server ("\012", 0);
4944 #endif /* CLIENT_SUPPORT */