AMD64 - Fix format conversions and other warnings.
[dragonfly.git] / contrib / cvs-1.12 / src / checkout.c
blobbba93ca5a266c091b379f218023d87a982914c6c
1 /*
2 * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
4 * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
5 * and others.
7 * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
8 * Portions Copyright (C) 1989-1992, Brian Berliner
9 *
10 * You may distribute under the terms of the GNU General Public License as
11 * specified in the README file that comes with the CVS source distribution.
13 * Create Version
15 * "checkout" creates a "version" of an RCS repository. This version is owned
16 * totally by the user and is actually an independent copy, to be dealt with
17 * as seen fit. Once "checkout" has been called in a given directory, it
18 * never needs to be called again. The user can keep up-to-date by calling
19 * "update" when he feels like it; this will supply him with a merge of his
20 * own modifications and the changes made in the RCS original. See "update"
21 * for details.
23 * "checkout" can be given a list of directories or files to be updated and in
24 * the case of a directory, will recursivley create any sub-directories that
25 * exist in the repository.
27 * When the user is satisfied with his own modifications, the present version
28 * can be committed by "commit"; this keeps the present version in tact,
29 * usually.
31 * The call is cvs checkout [options] <module-name>...
33 * "checkout" creates a directory ./CVS, in which it keeps its administration,
34 * in two files, Repository and Entries. The first contains the name of the
35 * repository. The second contains one line for each registered file,
36 * consisting of the version number it derives from, its time stamp at
37 * derivation time and its name. Both files are normal files and can be
38 * edited by the user, if necessary (when the repository is moved, e.g.)
41 #include "cvs.h"
43 static char *findslash (char *start, char *p);
44 static int checkout_proc (int argc, char **argv, char *where,
45 char *mwhere, char *mfile, int shorten,
46 int local_specified, char *omodule,
47 char *msg);
49 static const char *const checkout_usage[] =
51 "Usage:\n %s %s [-ANPRcflnps] [-r rev] [-D date] [-d dir]\n",
52 " [-j rev1] [-j rev2] [-k kopt] modules...\n",
53 "\t-A\tReset any sticky tags/date/kopts.\n",
54 "\t-N\tDon't shorten module paths if -d specified.\n",
55 "\t-P\tPrune empty directories.\n",
56 "\t-R\tProcess directories recursively.\n",
57 "\t-c\t\"cat\" the module database.\n",
58 "\t-f\tForce a head revision match if tag/date not found.\n",
59 "\t-l\tLocal directory only, not recursive\n",
60 "\t-n\tDo not run module program (if any).\n",
61 "\t-p\tCheck out files to standard output (avoids stickiness).\n",
62 "\t-s\tLike -c, but include module status.\n",
63 "\t-r rev\tCheck out revision or tag. (implies -P) (is sticky)\n",
64 "\t-D date\tCheck out revisions as of date. (implies -P) (is sticky)\n",
65 "\t-d dir\tCheck out into dir instead of module name.\n",
66 "\t-k kopt\tUse RCS kopt -k option on checkout. (is sticky)\n",
67 "\t-j rev\tMerge in changes made between current revision and rev.\n",
68 "(Specify the --help global option for a list of other help options)\n",
69 NULL
72 static const char *const export_usage[] =
74 "Usage: %s %s [-NRfln] [-r tag] [-D date] [-d dir] [-k kopt] module...\n",
75 "\t-N\tDon't shorten module paths if -d specified.\n",
76 "\t-f\tForce a head revision match if tag/date not found.\n",
77 "\t-l\tLocal directory only, not recursive\n",
78 "\t-R\tProcess directories recursively (default).\n",
79 "\t-n\tDo not run module program (if any).\n",
80 "\t-r tag\tExport tagged revisions.\n",
81 "\t-D date\tExport revisions as of date.\n",
82 "\t-d dir\tExport into dir instead of module name.\n",
83 "\t-k kopt\tUse RCS kopt -k option on checkout.\n",
84 "(Specify the --help global option for a list of other help options)\n",
85 NULL
88 static int checkout_prune_dirs;
89 static int force_tag_match;
90 static int pipeout;
91 static int aflag;
92 static char *options;
93 static char *tag;
94 static bool tag_validated;
95 static char *date;
96 static char *join_rev1, *join_date1;
97 static char *join_rev2, *join_date2;
98 static bool join_tags_validated;
99 static char *preload_update_dir;
100 static char *history_name;
101 static enum mtype m_type;
104 checkout (int argc, char **argv)
106 int i;
107 int c;
108 DBM *db;
109 int cat = 0, err = 0, status = 0;
110 int run_module_prog = 1;
111 int local = 0;
112 int shorten = -1;
113 char *where = NULL;
114 const char *valid_options;
115 const char *const *valid_usage;
116 char *join_orig1, *join_orig2;
118 /* initialize static options */
119 force_tag_match = 1;
120 if (options)
122 free (options);
123 options = NULL;
125 tag = date = join_rev1 = join_date1 = join_rev2 = join_date2 =
126 join_orig1 = join_orig2 = preload_update_dir = NULL;
127 history_name = NULL;
128 tag_validated = join_tags_validated = false;
132 * A smaller subset of options are allowed for the export command, which
133 * is essentially like checkout, except that it hard-codes certain
134 * options to be default (like -kv) and takes care to remove the CVS
135 * directory when it has done its duty
137 if (strcmp (cvs_cmd_name, "export") == 0)
139 m_type = EXPORT;
140 valid_options = "+Nnk:d:flRQqr:D:";
141 valid_usage = export_usage;
143 else
145 m_type = CHECKOUT;
146 valid_options = "+ANnk:d:flRpQqcsr:D:j:P";
147 valid_usage = checkout_usage;
150 if (argc == -1)
151 usage (valid_usage);
153 ign_setup ();
154 wrap_setup ();
156 optind = 0;
157 while ((c = getopt (argc, argv, valid_options)) != -1)
159 switch (c)
161 case 'A':
162 aflag = 1;
163 break;
164 case 'N':
165 shorten = 0;
166 break;
167 case 'k':
168 if (options)
169 free (options);
170 options = RCS_check_kflag (optarg);
171 break;
172 case 'n':
173 run_module_prog = 0;
174 break;
175 case 'Q':
176 case 'q':
177 /* The CVS 1.5 client sends these options (in addition to
178 Global_option requests), so we must ignore them. */
179 if (!server_active)
180 error (1, 0,
181 "-q or -Q must be specified before \"%s\"",
182 cvs_cmd_name);
183 break;
184 case 'l':
185 local = 1;
186 break;
187 case 'R':
188 local = 0;
189 break;
190 case 'P':
191 checkout_prune_dirs = 1;
192 break;
193 case 'p':
194 pipeout = 1;
195 run_module_prog = 0; /* don't run module prog when piping */
196 noexec = 1; /* so no locks will be created */
197 break;
198 case 'c':
199 cat = 1;
200 break;
201 case 'd':
202 where = optarg;
203 if (shorten == -1)
204 shorten = 1;
205 break;
206 case 's':
207 cat = status = 1;
208 break;
209 case 'f':
210 force_tag_match = 0;
211 break;
212 case 'r':
213 parse_tagdate (&tag, &date, optarg);
214 checkout_prune_dirs = 1;
215 break;
216 case 'D':
217 if (date) free (date);
218 date = Make_Date (optarg);
219 checkout_prune_dirs = 1;
220 break;
221 case 'j':
222 if (join_rev2 || join_date2)
223 error (1, 0, "only two -j options can be specified");
224 if (join_rev1 || join_date1)
226 if (join_orig2) free (join_orig2);
227 join_orig2 = xstrdup (optarg);
228 parse_tagdate (&join_rev2, &join_date2, optarg);
230 else
232 if (join_orig1) free (join_orig1);
233 join_orig1 = xstrdup (optarg);
234 parse_tagdate (&join_rev1, &join_date1, optarg);
236 break;
237 case '?':
238 default:
239 usage (valid_usage);
240 break;
243 argc -= optind;
244 argv += optind;
246 if (shorten == -1)
247 shorten = 0;
249 if (cat && argc != 0)
250 error (1, 0, "-c and -s must not get any arguments");
252 if (!cat && argc == 0)
253 error (1, 0, "must specify at least one module or directory");
255 if (where && pipeout)
256 error (1, 0, "-d and -p are mutually exclusive");
258 if (m_type == EXPORT)
260 if (!tag && !date)
261 error (1, 0, "must specify a tag or date");
263 if (tag && isdigit (tag[0]))
264 error (1, 0, "tag `%s' must be a symbolic tag", tag);
267 #ifdef SERVER_SUPPORT
268 if (server_active && where != NULL)
270 server_pathname_check (where);
272 #endif
274 if (!cat && !pipeout && !safe_location (where))
276 error (1, 0, "Cannot check out files into the repository itself");
279 #ifdef CLIENT_SUPPORT
280 if (current_parsed_root->isremote)
282 int expand_modules;
284 start_server ();
286 ign_setup ();
288 expand_modules = (!cat && !pipeout
289 && supported_request ("expand-modules"));
291 if (expand_modules)
293 /* This is done here because we need to read responses
294 from the server before we send the command checkout or
295 export files. */
297 client_expand_modules (argc, argv, local);
300 if (!run_module_prog)
301 send_arg ("-n");
302 if (local)
303 send_arg ("-l");
304 if (pipeout)
305 send_arg ("-p");
306 if (!force_tag_match)
307 send_arg ("-f");
308 if (aflag)
309 send_arg ("-A");
310 if (!shorten)
311 send_arg ("-N");
312 if (checkout_prune_dirs && m_type == CHECKOUT)
313 send_arg ("-P");
314 client_prune_dirs = checkout_prune_dirs;
315 if (cat && !status)
316 send_arg ("-c");
317 if (where != NULL)
318 option_with_arg ("-d", where);
319 if (status)
320 send_arg ("-s");
321 if (options != NULL && options[0] != '\0')
322 send_arg (options);
323 option_with_arg ("-r", tag);
324 if (date)
325 client_senddate (date);
326 if (join_orig1)
327 option_with_arg ("-j", join_orig1);
328 if (join_orig2)
329 option_with_arg ("-j", join_orig2);
330 send_arg ("--");
332 if (expand_modules)
334 client_send_expansions (local, where, 1);
336 else
338 int i;
339 for (i = 0; i < argc; ++i)
340 send_arg (argv[i]);
341 client_nonexpanded_setup ();
344 send_to_server (m_type == EXPORT ? "export\012" : "co\012", 0);
345 return get_responses_and_close ();
347 #endif /* CLIENT_SUPPORT */
349 if (cat)
351 cat_module (status);
352 if (options)
354 free (options);
355 options = NULL;
357 return 0;
359 db = open_module ();
362 /* If we've specified something like "cvs co foo/bar baz/quux"
363 don't try to shorten names. There are a few cases in which we
364 could shorten (e.g. "cvs co foo/bar foo/baz"), but we don't
365 handle those yet. Better to have an extra directory created
366 than the thing checked out under the wrong directory name. */
368 if (argc > 1)
369 shorten = 0;
372 /* If we will be calling history_write, work out the name to pass
373 it. */
374 if (!pipeout)
376 if (!date)
377 history_name = tag;
378 else if (!tag)
379 history_name = date;
380 else
381 history_name = Xasprintf ("%s:%s", tag, date);
385 for (i = 0; i < argc; i++)
386 err += do_module (db, argv[i], m_type, "Updating", checkout_proc,
387 where, shorten, local, run_module_prog, !pipeout,
388 NULL);
389 close_module (db);
390 if (options)
392 free (options);
393 options = NULL;
395 if (history_name != tag && history_name != date && history_name != NULL)
396 free (history_name);
397 return err;
402 /* FIXME: This is and emptydir_name are in checkout.c for historical
403 reasons, probably want to move them. */
405 /* int
406 * safe_location ( char *where )
408 * Return true if where is a safe destination for a checkout.
410 * INPUTS
411 * where The requested destination directory.
413 * GLOBALS
414 * current_parsed_root->directory
415 * current_parsed_root->isremote
416 * Used to locate our CVSROOT.
418 * RETURNS
419 * true If we are running in client mode or if where is not located
420 * within the CVSROOT.
421 * false Otherwise.
423 * ERRORS
424 * Exits with a fatal error message when various events occur, such as not
425 * being able to resolve a path or failing ot chdir to a path.
428 safe_location (char *where)
430 char *current;
431 char *hardpath;
432 size_t hardpath_len;
433 int retval;
435 TRACE (TRACE_FUNCTION, "safe_location( where=%s )",
436 where ? where : "(null)");
438 /* Don't compare remote CVSROOTs to our destination directory. */
439 if (current_parsed_root->isremote) return 1;
441 /* set current - even if where is set we'll need to cd back... */
442 current = xgetcwd ();
443 if (current == NULL)
444 error (1, errno, "could not get working directory");
446 hardpath = xcanonicalize_file_name (current_parsed_root->directory);
448 /* if where is set, set current to as much of where as exists,
449 * or fail.
451 if (where != NULL)
453 char *where_this_pass = xstrdup (where);
454 while (1)
456 if (CVS_CHDIR (where_this_pass) != -1)
458 /* where */
459 free (where_this_pass);
460 where_this_pass = xgetcwd ();
461 if (where_this_pass == NULL)
462 error (1, errno, "could not get working directory");
464 if (CVS_CHDIR (current) == -1)
465 error (1, errno,
466 "could not restore directory to `%s'", current);
468 free (current);
469 current = where_this_pass;
470 break;
472 else if (errno == ENOENT)
474 /* where_this_pass - last_component (where_this_pass) */
475 char *parent;
477 /* It's okay to cast out the const below since we know we
478 * allocated where_this_pass and have control of it.
480 if ((parent = (char *)last_component (where_this_pass))
481 != where_this_pass)
483 /* strip the last_component */
484 parent[-1] = '\0';
485 /* continue */
487 else
489 /* ERRNO == ENOENT
490 * && last_component (where_this_pass) == where_this_pass
491 * means we've tried all the parent diretories and not one
492 * exists, so there is no need to test any portion of where
493 * - it is all being created.
495 free (where_this_pass);
496 break;
499 else
500 /* we don't know how to handle other errors, so fail */
501 error (1, errno, "\
502 could not change directory to requested checkout directory `%s'",
503 where_this_pass);
504 } /* while (1) */
505 } /* where != NULL */
507 hardpath_len = strlen (hardpath);
508 if (strlen (current) >= hardpath_len
509 && strncmp (current, hardpath, hardpath_len) == 0)
511 if (/* Current is a subdirectory of hardpath. */
512 current[hardpath_len] == '/'
514 /* Current is hardpath itself. */
515 || current[hardpath_len] == '\0')
516 retval = 0;
517 else
518 /* It isn't a problem. For example, current is
519 "/foo/cvsroot-bar" and hardpath is "/foo/cvsroot". */
520 retval = 1;
522 else
523 retval = 1;
524 free (current);
525 free (hardpath);
526 return retval;
531 struct dir_to_build
533 /* What to put in CVS/Repository. */
534 char *repository;
535 /* The path to the directory. */
536 char *dirpath;
538 struct dir_to_build *next;
543 static int build_dirs_and_chdir (struct dir_to_build *list,
544 int sticky);
546 static void
547 build_one_dir (char *repository, char *dirpath, int sticky)
549 FILE *fp;
551 if (isfile (CVSADM))
553 if (m_type == EXPORT)
554 error (1, 0, "cannot export into a working directory");
556 else if (m_type == CHECKOUT)
558 /* I suspect that this check could be omitted. */
559 if (!isdir (repository))
560 error (1, 0, "there is no repository %s", repository);
562 if (Create_Admin (".", dirpath, repository,
563 sticky ? tag : NULL,
564 sticky ? date : NULL,
566 /* FIXME? This is a guess. If it is important
567 for nonbranch to be set correctly here I
568 think we need to write it one way now and
569 then rewrite it later via WriteTag, once
570 we've had a chance to call RCS_nodeisbranch
571 on each file. */
572 0, 1, 1))
573 return;
575 if (!noexec)
577 fp = xfopen (CVSADM_ENTSTAT, "w+");
578 if (fclose (fp) == EOF)
579 error (1, errno, "cannot close %s", CVSADM_ENTSTAT);
580 #ifdef SERVER_SUPPORT
581 if (server_active)
582 server_set_entstat (dirpath, repository);
583 #endif
591 * process_module calls us back here so we do the actual checkout stuff
593 /* ARGSUSED */
594 static int
595 checkout_proc (int argc, char **argv, char *where_orig, char *mwhere,
596 char *mfile, int shorten, int local_specified, char *omodule,
597 char *msg)
599 char *myargv[2];
600 int err = 0;
601 int which;
602 char *cp;
603 char *repository;
604 char *oldupdate = NULL;
605 char *where;
607 TRACE (TRACE_FUNCTION, "checkout_proc (%s, %s, %s, %d, %d, %s, %s)\n",
608 where_orig ? where_orig : "(null)",
609 mwhere ? mwhere : "(null)",
610 mfile ? mfile : "(null)",
611 shorten, local_specified,
612 omodule ? omodule : "(null)",
613 msg ? msg : "(null)"
617 * OK, so we're doing the checkout! Our args are as follows:
618 * argc,argv contain either dir or dir followed by a list of files
619 * where contains where to put it (if supplied by checkout)
620 * mwhere contains the module name or -d from module file
621 * mfile says do only that part of the module
622 * shorten = 1 says shorten as much as possible
623 * omodule is the original arg to do_module()
626 /* Set up the repository (maybe) for the bottom directory.
627 Allocate more space than we need so we don't need to keep
628 reallocating this string. */
629 repository = xmalloc (strlen (current_parsed_root->directory)
630 + strlen (argv[0])
631 + (mfile == NULL ? 0 : strlen (mfile))
632 + 10);
633 (void) sprintf (repository, "%s/%s",
634 current_parsed_root->directory, argv[0]);
635 Sanitize_Repository_Name (repository);
638 /* save the original value of preload_update_dir */
639 if (preload_update_dir != NULL)
640 oldupdate = xstrdup (preload_update_dir);
643 /* Allocate space and set up the where variable. We allocate more
644 space than necessary here so that we don't have to keep
645 reallocaing it later on. */
647 where = xmalloc (strlen (argv[0])
648 + (mfile == NULL ? 0 : strlen (mfile))
649 + (mwhere == NULL ? 0 : strlen (mwhere))
650 + (where_orig == NULL ? 0 : strlen (where_orig))
651 + 10);
653 /* Yes, this could be written in a less verbose way, but in this
654 form it is quite easy to read.
656 FIXME? The following code that sets should probably be moved
657 to do_module in modules.c, since there is similar code in
658 patch.c and rtag.c. */
660 if (shorten)
662 if (where_orig != NULL)
664 /* If the user has specified a directory with `-d' on the
665 command line, use it preferentially, even over the `-d'
666 flag in the modules file. */
668 (void) strcpy (where, where_orig);
670 else if (mwhere != NULL)
672 /* Second preference is the value of mwhere, which is from
673 the `-d' flag in the modules file. */
675 (void) strcpy (where, mwhere);
677 else
679 /* Third preference is the directory specified in argv[0]
680 which is this module'e directory in the repository. */
682 (void) strcpy (where, argv[0]);
685 else
687 /* Use the same preferences here, bug don't shorten -- that
688 is, tack on where_orig if it exists. */
690 *where = '\0';
692 if (where_orig != NULL)
694 (void) strcat (where, where_orig);
695 (void) strcat (where, "/");
698 /* If the -d flag in the modules file specified an absolute
699 directory, let the user override it with the command-line
700 -d option. */
702 if (mwhere && !ISABSOLUTE (mwhere))
703 (void) strcat (where, mwhere);
704 else
705 (void) strcat (where, argv[0]);
707 strip_trailing_slashes (where); /* necessary? */
710 /* At this point, the user may have asked for a single file or
711 directory from within a module. In that case, we should modify
712 where, repository, and argv as appropriate. */
714 if (mfile != NULL)
716 /* The mfile variable can have one or more path elements. If
717 it has multiple elements, we want to tack those onto both
718 repository and where. The last element may refer to either
719 a file or directory. Here's what to do:
721 it refers to a directory
722 -> simply tack it on to where and repository
723 it refers to a file
724 -> munge argv to contain `basename mfile` */
726 char *cp;
727 char *path;
730 /* Paranoia check. */
732 if (mfile[strlen (mfile) - 1] == '/')
734 error (0, 0, "checkout_proc: trailing slash on mfile (%s)!",
735 mfile);
739 /* Does mfile have multiple path elements? */
741 cp = strrchr (mfile, '/');
742 if (cp != NULL)
744 *cp = '\0';
745 (void) strcat (repository, "/");
746 (void) strcat (repository, mfile);
747 (void) strcat (where, "/");
748 (void) strcat (where, mfile);
749 mfile = cp + 1;
753 /* Now mfile is a single path element. */
755 path = Xasprintf ("%s/%s", repository, mfile);
756 if (isdir (path))
758 /* It's a directory, so tack it on to repository and
759 where, as we did above. */
761 (void) strcat (repository, "/");
762 (void) strcat (repository, mfile);
763 (void) strcat (where, "/");
764 (void) strcat (where, mfile);
766 else
768 /* It's a file, which means we have to screw around with
769 argv. */
770 myargv[0] = argv[0];
771 myargv[1] = mfile;
772 argc = 2;
773 argv = myargv;
775 free (path);
778 if (preload_update_dir != NULL)
780 preload_update_dir =
781 xrealloc (preload_update_dir,
782 strlen (preload_update_dir) + strlen (where) + 5);
783 strcat (preload_update_dir, "/");
784 strcat (preload_update_dir, where);
786 else
787 preload_update_dir = xstrdup (where);
790 * At this point, where is the directory we want to build, repository is
791 * the repository for the lowest level of the path.
793 * We need to tell build_dirs not only the path we want it to
794 * build, but also the repositories we want it to populate the
795 * path with. To accomplish this, we walk the path backwards, one
796 * pathname component at a time, constucting a linked list of
797 * struct dir_to_build.
801 * If we are sending everything to stdout, we can skip a whole bunch of
802 * work from here
804 if (!pipeout)
806 struct dir_to_build *head;
807 char *reposcopy;
809 if (strncmp (repository, current_parsed_root->directory,
810 strlen (current_parsed_root->directory)) != 0)
811 error (1, 0, "\
812 internal error: %s doesn't start with %s in checkout_proc",
813 repository, current_parsed_root->directory);
815 /* We always create at least one directory, which corresponds to
816 the entire strings for WHERE and REPOSITORY. */
817 head = xmalloc (sizeof (struct dir_to_build));
818 /* Special marker to indicate that we don't want build_dirs_and_chdir
819 to create the CVSADM directory for us. */
820 head->repository = NULL;
821 head->dirpath = xstrdup (where);
822 head->next = NULL;
824 /* Make a copy of the repository name to play with. */
825 reposcopy = xstrdup (repository);
827 /* FIXME: this should be written in terms of last_component
828 instead of hardcoding '/'. This presumably affects OS/2,
829 NT, &c, if the user specifies '\'. Likewise for the call
830 to findslash. */
831 cp = where + strlen (where);
832 while (cp > where)
834 struct dir_to_build *new;
836 cp = findslash (where, cp - 1);
837 if (cp == NULL)
838 break; /* we're done */
840 new = xmalloc (sizeof (struct dir_to_build));
841 new->dirpath = xmalloc (strlen (where));
843 /* If the user specified an absolute path for where, the
844 last path element we create should be the top-level
845 directory. */
847 if (cp > where)
849 strncpy (new->dirpath, where, cp - where);
850 new->dirpath[cp - where] = '\0';
852 else
854 /* where should always be at least one character long. */
855 assert (where[0] != '\0');
856 strcpy (new->dirpath, "/");
858 new->next = head;
859 head = new;
861 /* Now figure out what repository directory to generate.
862 The most complete case would be something like this:
864 The modules file contains
865 foo -d bar/baz quux
867 The command issued was:
868 cvs co -d what/ever -N foo
870 The results in the CVS/Repository files should be:
871 . -> (don't touch CVS/Repository)
872 (I think this case might be buggy currently)
873 what -> (don't touch CVS/Repository)
874 ever -> . (same as "cd what/ever; cvs co -N foo")
875 bar -> Emptydir (generated dir -- not in repos)
876 baz -> quux (finally!) */
878 if (strcmp (reposcopy, current_parsed_root->directory) == 0)
880 /* We can't walk up past CVSROOT. Instead, the
881 repository should be Emptydir. */
882 new->repository = emptydir_name ();
884 else
886 /* It's a directory in the repository! */
888 char *rp;
890 /* We'll always be below CVSROOT, but check for
891 paranoia's sake. */
892 rp = strrchr (reposcopy, '/');
893 if (rp == NULL)
894 error (1, 0,
895 "internal error: %s doesn't contain a slash",
896 reposcopy);
898 *rp = '\0';
900 if (strcmp (reposcopy, current_parsed_root->directory) == 0)
902 /* Special case -- the repository name needs
903 to be "/path/to/repos/." (the trailing dot
904 is important). We might be able to get rid
905 of this after the we check out the other
906 code that handles repository names. */
907 new-> repository = Xasprintf ("%s/.", reposcopy);
909 else
910 new->repository = xstrdup (reposcopy);
914 /* clean up */
915 free (reposcopy);
917 /* The top-level CVSADM directory should always be
918 current_parsed_root->directory. Create it, but only if WHERE is
919 relative. If WHERE is absolute, our current directory
920 may not have a thing to do with where the sources are
921 being checked out. If it does, build_dirs_and_chdir
922 will take care of creating adm files here. */
923 /* FIXME: checking where_is_absolute is a horrid kludge;
924 I suspect we probably can just skip the call to
925 build_one_dir whenever the -d command option was specified
926 to checkout. */
928 if (!ISABSOLUTE (where) && config->top_level_admin
929 && m_type == CHECKOUT)
931 /* It may be argued that we shouldn't set any sticky
932 bits for the top-level repository. FIXME? */
933 build_one_dir (current_parsed_root->directory, ".", argc <= 1);
935 #ifdef SERVER_SUPPORT
936 /* We _always_ want to have a top-level admin
937 directory. If we're running in client/server mode,
938 send a "Clear-static-directory" command to make
939 sure it is created on the client side. (See 5.10
940 in cvsclient.dvi to convince yourself that this is
941 OK.) If this is a duplicate command being sent, it
942 will be ignored on the client side. */
944 if (server_active)
945 server_clear_entstat (".", current_parsed_root->directory);
946 #endif
950 /* Build dirs on the path if necessary and leave us in the
951 bottom directory (where if where was specified) doesn't
952 contain a CVS subdir yet, but all the others contain
953 CVS and Entries.Static files */
955 if (build_dirs_and_chdir (head, argc <= 1) != 0)
957 error (0, 0, "ignoring module %s", omodule);
958 err = 1;
959 goto out;
962 /* set up the repository (or make sure the old one matches) */
963 if (!isfile (CVSADM))
965 FILE *fp;
967 if (!noexec && argc > 1)
969 /* I'm not sure whether this check is redundant. */
970 if (!isdir (repository))
971 error (1, 0, "there is no repository %s", repository);
973 Create_Admin (".", preload_update_dir, repository,
974 NULL, NULL, 0, 0, m_type == CHECKOUT);
975 fp = xfopen (CVSADM_ENTSTAT, "w+");
976 if (fclose (fp) == EOF)
977 error (1, errno, "cannot close %s", CVSADM_ENTSTAT);
978 #ifdef SERVER_SUPPORT
979 if (server_active)
980 server_set_entstat (where, repository);
981 #endif
983 else
985 /* I'm not sure whether this check is redundant. */
986 if (!isdir (repository))
987 error (1, 0, "there is no repository %s", repository);
989 Create_Admin (".", preload_update_dir, repository, tag, date,
991 /* FIXME? This is a guess. If it is important
992 for nonbranch to be set correctly here I
993 think we need to write it one way now and
994 then rewrite it later via WriteTag, once
995 we've had a chance to call RCS_nodeisbranch
996 on each file. */
997 0, 0, m_type == CHECKOUT);
1000 else
1002 char *repos;
1004 if (m_type == EXPORT)
1005 error (1, 0, "cannot export into working directory");
1007 /* get the contents of the previously existing repository */
1008 repos = Name_Repository (NULL, preload_update_dir);
1009 if (fncmp (repository, repos) != 0)
1011 char *prepos = xstrdup (primary_root_inverse_translate (repos));
1012 char *prepository =
1013 xstrdup (primary_root_inverse_translate (repository));
1014 error (0, 0, "existing repository %s does not match %s",
1015 prepos, prepository);
1016 error (0, 0, "ignoring module %s", omodule);
1017 free (repos);
1018 free (prepos);
1019 free (prepository);
1020 err = 1;
1021 goto out;
1023 free (repos);
1028 * If we are going to be updating to stdout, we need to cd to the
1029 * repository directory so the recursion processor can use the current
1030 * directory as the place to find repository information
1032 if (pipeout)
1034 if (CVS_CHDIR (repository) < 0)
1036 error (0, errno, "cannot chdir to %s", repository);
1037 err = 1;
1038 goto out;
1040 which = W_REPOS;
1041 if (tag && !tag_validated)
1043 tag_check_valid (tag, argc - 1, argv + 1, 0, aflag,
1044 repository, false);
1045 tag_validated = true;
1048 else
1050 which = W_LOCAL | W_REPOS;
1051 if (tag && !tag_validated)
1053 tag_check_valid (tag, argc - 1, argv + 1, 0, aflag,
1054 repository, false);
1055 tag_validated = true;
1059 if (tag || date || join_rev1 || join_date2)
1060 which |= W_ATTIC;
1062 if (!join_tags_validated)
1064 if (join_rev1)
1065 tag_check_valid (join_rev1, argc - 1, argv + 1, 0, aflag,
1066 repository, false);
1067 if (join_rev2)
1068 tag_check_valid (join_rev2, argc - 1, argv + 1, 0, aflag,
1069 repository, false);
1070 join_tags_validated = true;
1074 * if we are going to be recursive (building dirs), go ahead and call the
1075 * update recursion processor. We will be recursive unless either local
1076 * only was specified, or we were passed arguments
1078 if (!(local_specified || argc > 1))
1080 if (!pipeout)
1081 history_write (m_type == CHECKOUT ? 'O' : 'E', preload_update_dir,
1082 history_name, where, repository);
1083 err += do_update (0, NULL, options, tag, date,
1084 force_tag_match, false /* !local */ ,
1085 true /* update -d */ , aflag, checkout_prune_dirs,
1086 pipeout, which, join_rev1, join_date1,
1087 join_rev2, join_date2,
1088 preload_update_dir, m_type == CHECKOUT,
1089 repository);
1090 goto out;
1093 if (!pipeout)
1095 int i;
1096 List *entries;
1098 /* we are only doing files, so register them */
1099 entries = Entries_Open (0, NULL);
1100 for (i = 1; i < argc; i++)
1102 char *line;
1103 Vers_TS *vers;
1104 struct file_info finfo;
1106 memset (&finfo, 0, sizeof finfo);
1107 finfo.file = argv[i];
1108 /* Shouldn't be used, so set to arbitrary value. */
1109 finfo.update_dir = NULL;
1110 finfo.fullname = argv[i];
1111 finfo.repository = repository;
1112 finfo.entries = entries;
1113 /* The rcs slot is needed to get the options from the RCS
1114 file */
1115 finfo.rcs = RCS_parse (finfo.file, repository);
1117 vers = Version_TS (&finfo, options, tag, date,
1118 force_tag_match, 0);
1119 if (vers->ts_user == NULL)
1121 line = Xasprintf ("Initial %s", finfo.file);
1122 Register (entries, finfo.file,
1123 vers->vn_rcs ? vers->vn_rcs : "0",
1124 line, vers->options, vers->tag,
1125 vers->date, NULL);
1126 free (line);
1128 freevers_ts (&vers);
1129 freercsnode (&finfo.rcs);
1132 Entries_Close (entries);
1135 /* Don't log "export", just regular "checkouts" */
1136 if (m_type == CHECKOUT && !pipeout)
1137 history_write ('O', preload_update_dir, history_name, where,
1138 repository);
1140 /* go ahead and call update now that everything is set */
1141 err += do_update (argc - 1, argv + 1, options, tag, date,
1142 force_tag_match, local_specified, true /* update -d */,
1143 aflag, checkout_prune_dirs, pipeout, which, join_rev1,
1144 join_date1, join_rev2, join_date2, preload_update_dir,
1145 m_type == CHECKOUT, repository);
1146 out:
1147 free (preload_update_dir);
1148 preload_update_dir = oldupdate;
1149 free (where);
1150 free (repository);
1151 return err;
1156 static char *
1157 findslash (char *start, char *p)
1159 for (;;)
1161 if (*p == '/') return p;
1162 if (p == start) break;
1163 --p;
1165 return NULL;
1170 /* Return a newly malloc'd string containing a pathname for CVSNULLREPOS,
1171 and make sure that it exists. If there is an error creating the
1172 directory, give a fatal error. Otherwise, the directory is guaranteed
1173 to exist when we return. */
1174 char *
1175 emptydir_name (void)
1177 char *repository;
1179 repository = Xasprintf ("%s/%s/%s", current_parsed_root->directory,
1180 CVSROOTADM, CVSNULLREPOS);
1181 if (!isfile (repository))
1183 mode_t omask;
1184 omask = umask (cvsumask);
1185 if (CVS_MKDIR (repository, 0777) < 0)
1186 error (1, errno, "cannot create %s", repository);
1187 (void) umask (omask);
1189 return repository;
1194 /* Build all the dirs along the path to DIRS with CVS subdirs with appropriate
1195 * repositories. If DIRS->repository is NULL or the directory already exists,
1196 * do not create a CVSADM directory for that subdirectory; just CVS_CHDIR into
1197 * it. Frees all storage used by DIRS.
1199 * ASSUMPTIONS
1200 * 1. Parent directories will be listed in DIRS before their children.
1201 * 2. At most a single directory will need to be changed at one time. In
1202 * other words, if we are in /a/b/c, and our final destination is
1203 * /a/b/c/d/e/f, then we will build d, then d/e, then d/e/f.
1205 * INPUTS
1206 * dirs Simple list composed of dir_to_build structures, listing
1207 * information about directories to build.
1208 * sticky Passed to build_one_dir to tell it whether there are any sticky
1209 * tags or dates to be concerned with.
1211 * RETURNS
1212 * 1 on error, 0 otherwise.
1214 * ERRORS
1215 * The only nonfatal error this function may return is if the CHDIR fails.
1217 static int
1218 build_dirs_and_chdir (struct dir_to_build *dirs, int sticky)
1220 int retval = 0;
1221 struct dir_to_build *nextdir;
1223 while (dirs != NULL)
1225 const char *dir = last_component (dirs->dirpath);
1226 int made_dir = 0;
1228 made_dir = !mkdir_if_needed (dir);
1229 if (made_dir) Subdir_Register (NULL, NULL, dir);
1231 if (CVS_CHDIR (dir) < 0)
1233 error (0, errno, "cannot chdir to %s", dir);
1234 retval = 1;
1235 goto out;
1237 if (dirs->repository != NULL)
1239 if (made_dir)
1240 build_one_dir (dirs->repository, dirs->dirpath, sticky);
1241 free (dirs->repository);
1243 nextdir = dirs->next;
1244 free (dirs->dirpath);
1245 free (dirs);
1246 dirs = nextdir;
1249 out:
1250 while (dirs != NULL)
1252 if (dirs->repository != NULL)
1253 free (dirs->repository);
1254 nextdir = dirs->next;
1255 free (dirs->dirpath);
1256 free (dirs);
1257 dirs = nextdir;
1259 return retval;