home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / misc / amicvs1-0.lha / AmiCVS / scr / checkout.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-29  |  18.7 KB  |  720 lines

  1. /*
  2.  * Copyright (c) 1992, Brian Berliner and Jeff Polk
  3.  * Copyright (c) 1989-1992, Brian Berliner
  4.  * 
  5.  * You may distribute under the terms of the GNU General Public License as
  6.  * specified in the README file that comes with the CVS 1.3 kit.
  7.  * 
  8.  * Create Version
  9.  * 
  10.  * "checkout" creates a "version" of an RCS repository.  This version is owned
  11.  * totally by the user and is actually an independent copy, to be dealt with
  12.  * as seen fit.  Once "checkout" has been called in a given directory, it
  13.  * never needs to be called again.  The user can keep up-to-date by calling
  14.  * "update" when he feels like it; this will supply him with a merge of his
  15.  * own modifications and the changes made in the RCS original.  See "update"
  16.  * for details.
  17.  * 
  18.  * "checkout" can be given a list of directories or files to be updated and in
  19.  * the case of a directory, will recursivley create any sub-directories that
  20.  * exist in the repository.
  21.  * 
  22.  * When the user is satisfied with his own modifications, the present version
  23.  * can be committed by "commit"; this keeps the present version in tact,
  24.  * usually.
  25.  * 
  26.  * The call is cvs checkout [options] <module-name>...
  27.  * 
  28.  * "checkout" creates a directory ./CVS, in which it keeps its administration,
  29.  * in two files, Repository and Entries. The first contains the name of the
  30.  * repository.  The second contains one line for each registered file,
  31.  * consisting of the version number it derives from, its time stamp at
  32.  * derivation time and its name.  Both files are normal files and can be
  33.  * edited by the user, if necessary (when the repository is moved, e.g.)
  34.  */
  35.  
  36. #include "cvs.h"
  37.  
  38. #ifndef lint
  39. static char rcsid[] = "@(#)checkout.c 1.67 92/04/10";
  40. #endif
  41.  
  42. #if __STDC__
  43. static char *findslash (char *start, char *p);
  44. static int build_dirs_and_chdir (char *dir, char *prepath, char *realdir,
  45.                  int sticky);
  46. static int checkout_proc (int *pargc, char *argv[], char *where,
  47.                   char *mwhere, char *mfile, int shorten,
  48.                   int local_specified, char *omodule,
  49.                   char *msg);
  50. #else
  51. static int checkout_proc ();
  52. static char *findslash ();
  53. static int build_dirs_and_chdir ();
  54. #endif                /* __STDC__ */
  55.  
  56. static char *checkout_usage[] =
  57. {
  58.     "Usage:\n  %s %s [-ANPQcflnpqs] [-r rev | -D date] [-d dir] [-k kopt] modules...\n",
  59.     "\t-A\tReset any sticky tags/date/kopts.\n",
  60.     "\t-N\tDon't shorten module paths if -d specified.\n",
  61.     "\t-P\tPrune empty directories.\n",
  62.     "\t-Q\tReally quiet.\n",
  63.     "\t-c\t\"cat\" the module database.\n",
  64.     "\t-f\tForce a head revision match if tag/date not found.\n",
  65.     "\t-l\tLocal directory only, not recursive\n",
  66.     "\t-n\tDo not run module program (if any).\n",
  67.     "\t-p\tCheck out files to standard output.\n",
  68.     "\t-q\tSomewhat quiet.\n",
  69.     "\t-s\tLike -c, but include module status.\n",
  70.     "\t-r rev\tCheck out revision or tag. (implies -P)\n",
  71.     "\t-D date\tCheck out revisions as of date. (implies -P)\n",
  72.     "\t-d dir\tCheck out into dir instead of module name.\n",
  73.     "\t-k kopt\tUse RCS kopt -k option on checkout.\n",
  74.     "\t-j rev\tMerge in changes made between current revision and rev.\n",
  75.     NULL
  76. };
  77.  
  78. static char *export_usage[] =
  79. {
  80.     "Usage: %s %s [-NPQflnq] [-r rev | -D date] [-d dir] module...\n",
  81.     "\t-N\tDon't shorten module paths if -d specified.\n",
  82.     "\t-Q\tReally quiet.\n",
  83.     "\t-f\tForce a head revision match if tag/date not found.\n",
  84.     "\t-l\tLocal directory only, not recursive\n",
  85.     "\t-n\tDo not run module program (if any).\n",
  86.     "\t-q\tSomewhat quiet.\n",
  87.     "\t-r rev\tCheck out revision or tag. (implies -P)\n",
  88.     "\t-D date\tCheck out revisions as of date. (implies -P)\n",
  89.     "\t-d dir\tCheck out into dir instead of module name.\n",
  90.     NULL
  91. };
  92.  
  93. static int checkout_prune_dirs;
  94. static int force_tag_match = 1;
  95. static int pipeout;
  96. static int aflag;
  97. static char *options = NULL;
  98. static char *tag = NULL;
  99. static char *date = NULL;
  100. static char *join_rev1 = NULL;
  101. static char *join_rev2 = NULL;
  102. static char *preload_update_dir = NULL;
  103.  
  104. int
  105. checkout (argc, argv)
  106.     int argc;
  107.     char *argv[];
  108. {
  109.     register int i;
  110.     int c;
  111.     DBM *db;
  112.     int cat = 0, err = 0, status = 0;
  113.     int run_module_prog = 1;
  114.     int local = 0;
  115.     int shorten = -1;
  116.     char *where = NULL;
  117.     char *valid_options, **valid_usage;
  118.  
  119.     /*
  120.      * A smaller subset of options are allowed for the export command, which
  121.      * is essentially like checkout, except that it hard-codes certain
  122.      * options to be on (like -kv) and takes care to remove the CVS directory
  123.      * when it has done its duty
  124.      */
  125.     if (strcmp (command_name, "export") == 0)
  126.     {
  127.     valid_options = "Nnd:flRQqr:D:";
  128.     valid_usage = export_usage;
  129.     }
  130.     else
  131.     {
  132.     valid_options = "ANnk:d:flRpQqcsr:D:j:P";
  133.     valid_usage = checkout_usage;
  134.     }
  135.  
  136.     if (argc == -1)
  137.     usage (valid_usage);
  138.  
  139.     ign_setup ();
  140.  
  141.     optind = 1;
  142.     while ((c = gnu_getopt (argc, argv, valid_options)) != -1)
  143.     {
  144.     switch (c)
  145.     {
  146.         case 'A':
  147.         aflag = 1;
  148.         break;
  149.         case 'N':
  150.         shorten = 0;
  151.         break;
  152.         case 'k':
  153.         if (options)
  154.             free (options);
  155.         options = RCS_check_kflag (optarg);
  156.         break;
  157.         case 'n':
  158.         run_module_prog = 0;
  159.         break;
  160.         case 'Q':
  161.         really_quiet = 1;
  162.         /* FALL THROUGH */
  163.         case 'q':
  164.         quiet = 1;
  165.         break;
  166.         case 'l':
  167.         local = 1;
  168.         break;
  169.         case 'R':
  170.         local = 0;
  171.         break;
  172.         case 'P':
  173.         checkout_prune_dirs = 1;
  174.         break;
  175.         case 'p':
  176.         pipeout = 1;
  177.         run_module_prog = 0;    /* don't run module prog when piping */
  178.         noexec = 1;        /* so no locks will be created */
  179.         break;
  180.         case 'c':
  181.         cat = 1;
  182.         break;
  183.         case 'd':
  184.         where = optarg;
  185.         if (shorten == -1)
  186.             shorten = 1;
  187.         break;
  188.         case 's':
  189.         status = 1;
  190.         break;
  191.         case 'f':
  192.         force_tag_match = 0;
  193.         break;
  194.         case 'r':
  195.         tag = optarg;
  196.         checkout_prune_dirs = 1;
  197.         break;
  198.         case 'D':
  199.         date = Make_Date (optarg);
  200.         checkout_prune_dirs = 1;
  201.         break;
  202.         case 'j':
  203.         if (join_rev2)
  204.             error (1, 0, "only two -j options can be specified");
  205.         if (join_rev1)
  206.             join_rev2 = optarg;
  207.         else
  208.             join_rev1 = optarg;
  209.         break;
  210.         case '?':
  211.         default:
  212.         usage (valid_usage);
  213.         break;
  214.     }
  215.     }
  216.     argc -= optind;
  217.     argv += optind;
  218.  
  219.     if (shorten == -1)
  220.     shorten = 0;
  221.  
  222.     if ((!(cat + status) && argc == 0) || ((cat + status) && argc != 0)
  223.     || (tag && date))
  224.     usage (valid_usage);
  225.  
  226.     if (where && pipeout)
  227.     error (1, 0, "-d and -p are mutually exclusive");
  228.  
  229.     if (strcmp (command_name, "export") == 0)
  230.     {
  231.     if (!tag && !date)
  232.     {
  233.         error (0, 0, "must specify a tag or date");
  234.         usage (valid_usage);
  235.     }
  236.     if (tag && isdigit (tag[0]))
  237.         error (1, 0, "tag `%s' must be a symbolic tag", tag);
  238.     options = RCS_check_kflag ("v");/* -kv must be on */
  239.     }
  240.  
  241.     if (cat || status)
  242.     {
  243.     cat_module (status);
  244.     return (0);
  245.     }
  246.     db = open_module ();
  247.  
  248.     /*
  249.      * if we have more than one argument and where was specified, we make the
  250.      * where, cd into it, and try to shorten names as much as possible.
  251.      * Otherwise, we pass the where as a single argument to do_module.
  252.      */
  253.     if (argc > 1 && where != NULL)
  254.     {
  255.     char repository[PATH_MAX];
  256.  
  257.     (void) mkdir (where, 0777);
  258.     if (chdir (where) < 0)
  259.         error (1, errno, "cannot chdir to %s", where);
  260.     preload_update_dir = xstrdup (where);
  261.     where = (char *) NULL;
  262.     if (!isfile (CVSADM) && !isfile (OCVSADM))
  263.     {
  264.         (void) sprintf (repository, "%s/%s", CVSroot, CVSNULLREPOS);
  265.         if (!isfile (repository))
  266.         (void) mkdir (repository, 0777);
  267.         Create_Admin (".", repository, (char *) NULL, (char *) NULL);
  268.         if (!noexec)
  269.         {
  270.         FILE *fp;
  271.  
  272.         fp = open_file (CVSADM_ENTSTAT, "w+");
  273.         if (fclose(fp) == EOF)
  274.             error(1, errno, "cannot close %s", CVSADM_ENTSTAT);
  275.         }
  276.     }
  277.     }
  278.  
  279.     /*
  280.      * if where was specified (-d) and we have not taken care of it already
  281.      * with the multiple arg stuff, and it was not a simple directory name
  282.      * but rather a path, we strip off everything but the last component and
  283.      * attempt to cd to the indicated place.  where then becomes simply the
  284.      * last component
  285.      */
  286.     if (where != NULL && index (where, '/') != NULL)
  287.     {
  288.     char *slash;
  289.  
  290.     slash = rindex (where, '/');
  291.     *slash = '\0';
  292.  
  293.     if (chdir (where) < 0)
  294.         error (1, errno, "cannot chdir to %s", where);
  295.  
  296.     preload_update_dir = xstrdup (where);
  297.  
  298.     where = slash + 1;
  299.     if (*where == '\0')
  300.         where = NULL;
  301.     }
  302.  
  303.     for (i = 0; i < argc; i++)
  304.     err += do_module (db, argv[i], CHECKOUT, "Updating", checkout_proc,
  305.               where, shorten, local, run_module_prog,
  306.               (char *) NULL);
  307.     close_module (db);
  308.     return (err);
  309. }
  310.  
  311. /*
  312.  * process_module calls us back here so we do the actual checkout stuff
  313.  */
  314. /* ARGSUSED */
  315. static int
  316. checkout_proc (pargc, argv, where, mwhere, mfile, shorten,
  317.            local_specified, omodule, msg)
  318.     int *pargc;
  319.     char *argv[];
  320.     char *where;
  321.     char *mwhere;
  322.     char *mfile;
  323.     int shorten;
  324.     int local_specified;
  325.     char *omodule;
  326.     char *msg;
  327. {
  328.     int err = 0;
  329.     int which;
  330.     char *cp;
  331.     char *cp2;
  332.     char repository[PATH_MAX];
  333.     char xwhere[PATH_MAX];
  334.     char *oldupdate = NULL;
  335.     char *prepath;
  336.     char *realdirs;
  337.  
  338.     /*
  339.      * OK, so we're doing the checkout! Our args are as follows: 
  340.      *  argc,argv contain either dir or dir followed by a list of files 
  341.      *  where contains where to put it (if supplied by checkout) 
  342.      *  mwhere contains the module name or -d from module file 
  343.      *  mfile says do only that part of the module
  344.      *  shorten = TRUE says shorten as much as possible 
  345.      *  omodule is the original arg to do_module()
  346.      */
  347.  
  348.     /* set up the repository (maybe) for the bottom directory */
  349.     (void) sprintf (repository, "%s/%s", CVSroot, argv[0]);
  350.  
  351.  
  352.     /* save the original value of preload_update_dir */
  353.     if (preload_update_dir != NULL)
  354.     oldupdate = xstrdup (preload_update_dir);
  355.  
  356.     /* fix up argv[] for the case of partial modules */
  357.     if (mfile != NULL)
  358.     {
  359.     char file[PATH_MAX];
  360.  
  361.     /* if mfile is really a path, straighten it out first */
  362.     if ((cp = rindex (mfile, '/')) != NULL)
  363.     {
  364.         *cp = 0;
  365.         (void) strcat (repository, "/");
  366.         (void) strcat (repository, mfile);
  367.  
  368.         /*
  369.          * Now we need to fill in the where correctly. if !shorten, tack
  370.          * the rest of the path onto where if where is filled in
  371.          * otherwise tack the rest of the path onto mwhere and make that
  372.          * the where
  373.          * 
  374.          * If shorten is enabled, we might use mwhere to set where if 
  375.          * nobody set it yet, so we'll need to setup mwhere as the last
  376.          * component of the path we are tacking onto repository
  377.          */
  378.         if (!shorten)
  379.         {
  380.         if (where != NULL)
  381.             (void) sprintf (xwhere, "%s/%s", where, mfile);
  382.         else
  383.             (void) sprintf (xwhere, "%s/%s", mwhere, mfile);
  384.         where = xwhere;
  385.         }
  386.         else
  387.         {
  388.         char *slash;
  389.  
  390.         if ((slash = rindex (mfile, '/')) != NULL)
  391.             mwhere = slash + 1;
  392.         else
  393.             mwhere = mfile;
  394.         }
  395.         mfile = cp + 1;
  396.     }
  397.  
  398.     (void) sprintf (file, "%s/%s", repository, mfile);
  399.     if (isdir (file))
  400.     {
  401.  
  402.         /*
  403.          * The portion of a module was a directory, so kludge up where to
  404.          * be the subdir, and fix up repository
  405.          */
  406.         (void) strcpy (repository, file);
  407.  
  408.         /*
  409.          * At this point, if shorten is not enabled, we make where either
  410.          * where with mfile concatenated, or if where hadn't been set we
  411.          * set it to mwhere with mfile concatenated.
  412.          * 
  413.          * If shorten is enabled and where hasn't been set yet, then where
  414.          * becomes mfile
  415.          */
  416.         if (!shorten)
  417.         {
  418.         if (where != NULL)
  419.             (void) sprintf (xwhere, "%s/%s", where, mfile);
  420.         else
  421.             (void) sprintf (xwhere, "%s/%s", mwhere, mfile);
  422.         where = xwhere;
  423.         }
  424.         else if (where == NULL)
  425.         where = mfile;
  426.     }
  427.     else
  428.     {
  429.         int i;
  430.  
  431.         /*
  432.          * The portion of a module was a file, so kludge up argv to be
  433.          * correct
  434.          */
  435.         for (i = 1; i < *pargc; i++)/* free the old ones */
  436.         free (argv[i]);
  437.         argv[1] = xstrdup (mfile);    /* set up the new one */
  438.         *pargc = 2;
  439.  
  440.         /* where gets mwhere if where isn't set */
  441.         if (where == NULL)
  442.         where = mwhere;
  443.     }
  444.     }
  445.  
  446.     /*
  447.      * if shorten is enabled and where isn't specified yet, we pluck the last
  448.      * directory component of argv[0] and make it the where
  449.      */
  450.     if (shorten && where == NULL)
  451.     {
  452.     if ((cp = rindex (argv[0], '/')) != NULL)
  453.     {
  454.         (void) strcpy (xwhere, cp + 1);
  455.         where = xwhere;
  456.     }
  457.     }
  458.  
  459.     /* if where is still NULL, use mwhere if set or the argv[0] dir */
  460.     if (where == NULL)
  461.     {
  462.     if (mwhere)
  463.         where = mwhere;
  464.     else
  465.     {
  466.         (void) strcpy (xwhere, argv[0]);
  467.         where = xwhere;
  468.     }
  469.     }
  470.  
  471.     if (preload_update_dir != NULL)
  472.     {
  473.     char tmp[PATH_MAX];
  474.  
  475.     (void) sprintf (tmp, "%s/%s", preload_update_dir, where);
  476.     free (preload_update_dir);
  477.     preload_update_dir = xstrdup (tmp);
  478.     }
  479.     else
  480.     preload_update_dir = xstrdup (where);
  481.  
  482.     /*
  483.      * At this point, where is the directory we want to build, repository is
  484.      * the repository for the lowest level of the path.
  485.      */
  486.  
  487.     /*
  488.      * If we are sending everything to stdout, we can skip a whole bunch of
  489.      * work from here
  490.      */
  491.     if (!pipeout)
  492.     {
  493.  
  494.     /*
  495.      * We need to tell build_dirs not only the path we want it to build,
  496.      * but also the repositories we want it to populate the path with. To
  497.      * accomplish this, we pass build_dirs a ``real path'' with valid
  498.      * repositories and a string to pre-pend based on how many path
  499.      * elements exist in where. Big Black Magic
  500.      */
  501.     prepath = xstrdup (repository);
  502.     cp = rindex (where, '/');
  503.     cp2 = rindex (prepath, '/');
  504.     while (cp != NULL)
  505.     {
  506.         cp = findslash (where, cp - 1);
  507.         cp2 = findslash (prepath, cp2 - 1);
  508.     }
  509.     *cp2 = '\0';
  510.     realdirs = cp2 + 1;
  511.  
  512.     /*
  513.      * build dirs on the path if necessary and leave us in the bottom
  514.      * directory (where if where was specified) doesn't contain a CVS
  515.      * subdir yet, but all the others contain CVS and Entries.Static
  516.      * files
  517.      */
  518.     if (build_dirs_and_chdir (where, prepath, realdirs, *pargc <= 1) != 0)
  519.     {
  520.         error (0, 0, "ignoring module %s", omodule);
  521.         free (prepath);
  522.         free (preload_update_dir);
  523.         preload_update_dir = oldupdate;
  524.         return (1);
  525.     }
  526.  
  527.     /* clean up */
  528.     free (prepath);
  529.  
  530.     /* set up the repository (or make sure the old one matches) */
  531.     if (!isfile (CVSADM) && !isfile (OCVSADM))
  532.     {
  533.         FILE *fp;
  534.  
  535.         if (!noexec && *pargc > 1)
  536.         {
  537.         Create_Admin (".", repository, (char *) NULL, (char *) NULL);
  538.         fp = open_file (CVSADM_ENTSTAT, "w+");
  539.         if (fclose(fp) == EOF)
  540.             error(1, errno, "cannot close %s", CVSADM_ENTSTAT);
  541.         }
  542.         else
  543.         Create_Admin (".", repository, tag, date);
  544.     }
  545.     else
  546.     {
  547.         char *repos;
  548.  
  549.         /* get the contents of the previously existing repository */
  550.         repos = Name_Repository ((char *) NULL, preload_update_dir);
  551.         if (strcmp (repository, repos) != 0)
  552.         {
  553.         error (0, 0, "existing repository %s does not match %s",
  554.                repos, repository);
  555.         error (0, 0, "ignoring module %s", omodule);
  556.         free (repos);
  557.         free (preload_update_dir);
  558.         preload_update_dir = oldupdate;
  559.         return (1);
  560.         }
  561.         free (repos);
  562.     }
  563.     }
  564.  
  565.     /*
  566.      * If we are going to be updating to stdout, we need to cd to the
  567.      * repository directory so the recursion processor can use the current
  568.      * directory as the place to find repository information
  569.      */
  570.     if (pipeout)
  571.     {
  572.     if (chdir (repository) < 0)
  573.     {
  574.         error (0, errno, "cannot chdir to %s", repository);
  575.         free (preload_update_dir);
  576.         preload_update_dir = oldupdate;
  577.         return (1);
  578.     }
  579.     which = W_REPOS;
  580.     }
  581.     else
  582.     which = W_LOCAL | W_REPOS;
  583.  
  584.     if (tag != NULL || date != NULL)
  585.     which |= W_ATTIC;
  586.  
  587.     /*
  588.      * if we are going to be recursive (building dirs), go ahead and call the
  589.      * update recursion processor.  We will be recursive unless either local
  590.      * only was specified, or we were passed arguments
  591.      */
  592.     if (!(local_specified || *pargc > 1))
  593.     {
  594.     if (strcmp (command_name, "export") != 0 && !pipeout)
  595.         history_write ('O', preload_update_dir, tag ? tag : date, where,
  596.                repository);
  597.     err += do_update (0, (char **) NULL, options, tag, date,
  598.               force_tag_match, 0 /* !local */ ,
  599.               1 /* update -d */ , aflag, checkout_prune_dirs,
  600.               pipeout, which, join_rev1, join_rev2,
  601.               preload_update_dir);
  602.     free (preload_update_dir);
  603.     preload_update_dir = oldupdate;
  604.     return (err);
  605.     }
  606.  
  607.     if (!pipeout)
  608.     {
  609.     int i;
  610.     List *entries;
  611.  
  612.     /* we are only doing files, so register them */
  613.     entries = ParseEntries (0);
  614.     for (i = 1; i < *pargc; i++)
  615.     {
  616.         char line[MAXLINELEN];
  617.         char *user;
  618.         Vers_TS *vers;
  619.  
  620.         user = argv[i];
  621.         vers = Version_TS (repository, options, tag, date, user,
  622.                    force_tag_match, 0, entries, (List *) NULL);
  623.         if (vers->ts_user == NULL)
  624.         {
  625.         (void) sprintf (line, "Initial %s", user);
  626.         Register (entries, user, vers->vn_rcs, line, vers->options,
  627.               vers->tag, vers->date);
  628.         }
  629.         freevers_ts (&vers);
  630.     }
  631.     dellist (&entries);
  632.     }
  633.  
  634.     /* Don't log "export", just regular "checkouts" */
  635.     if (strcmp (command_name, "export") != 0 && !pipeout)
  636.     history_write ('O', preload_update_dir, (tag ? tag : date), where,
  637.                repository);
  638.  
  639.     /* go ahead and call update now that everything is set */
  640.     err += do_update (*pargc - 1, argv + 1, options, tag, date,
  641.               force_tag_match, local_specified, 1 /* update -d */,
  642.               aflag, checkout_prune_dirs, pipeout, which, join_rev1,
  643.               join_rev2, preload_update_dir);
  644.     free (preload_update_dir);
  645.     preload_update_dir = oldupdate;
  646.     return (err);
  647. }
  648.  
  649. static char *
  650. findslash (start, p)
  651.     char *start;
  652.     char *p;
  653. {
  654.     while ((int) p >= (int) start && *p != '/')
  655.     p--;
  656.     if ((int) p < (int) start)
  657.     return (NULL);
  658.     else
  659.     return (p);
  660. }
  661.  
  662. /*
  663.  * build all the dirs along the path to dir with CVS subdirs with appropriate
  664.  * repositories and Entries.Static files
  665.  */
  666. static int
  667. build_dirs_and_chdir (dir, prepath, realdir, sticky)
  668.     char *dir;
  669.     char *prepath;
  670.     char *realdir;
  671.     int sticky;
  672. {
  673.     FILE *fp;
  674.     char repository[PATH_MAX];
  675.     char path[PATH_MAX];
  676.     char path2[PATH_MAX];
  677.     char *slash;
  678.     char *slash2;
  679.     char *cp;
  680.     char *cp2;
  681.  
  682.     (void) strcpy (path, dir);
  683.     (void) strcpy (path2, realdir);
  684.     for (cp = path, cp2 = path2;
  685.     (slash = index (cp, '/')) != NULL && (slash2 = index (cp2, '/')) != NULL;
  686.      cp = slash + 1, cp2 = slash2 + 1)
  687.     {
  688.     *slash = '\0';
  689.     *slash2 = '\0';
  690.     (void) mkdir (cp, 0777);
  691.     if (chdir (cp) < 0)
  692.     {
  693.         error (0, errno, "cannot chdir to %s", cp);
  694.         return (1);
  695.     }
  696.     if (!isfile (CVSADM) && !isfile (OCVSADM) &&
  697.         strcmp (command_name, "export") != 0)
  698.     {
  699.         (void) sprintf (repository, "%s/%s", prepath, path2);
  700.         Create_Admin (".", repository, sticky ? (char *) NULL : tag,
  701.               sticky ? (char *) NULL : date);
  702.         if (!noexec)
  703.         {
  704.         fp = open_file (CVSADM_ENTSTAT, "w+");
  705.         if (fclose(fp) == EOF)
  706.             error(1, errno, "cannot close %s", CVSADM_ENTSTAT);
  707.         }
  708.     }
  709.     *slash = '/';
  710.     *slash2 = '/';
  711.     }
  712.     (void) mkdir (cp, 0777);
  713.     if (chdir (cp) < 0)
  714.     {
  715.     error (0, errno, "cannot chdir to %s", cp);
  716.     return (1);
  717.     }
  718.     return (0);
  719. }
  720.