home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / cvs-1.8.7-src.tgz / tar.out / fsf / cvs / src / checkin.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  5KB  |  193 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.4 kit.
  7.  * 
  8.  * Check In
  9.  * 
  10.  * Does a very careful checkin of the file "user", and tries not to spoil its
  11.  * modification time (to avoid needless recompilations). When RCS ID keywords
  12.  * get expanded on checkout, however, the modification time is updated and
  13.  * there is no good way to get around this.
  14.  * 
  15.  * Returns non-zero on error.
  16.  */
  17.  
  18. #include "cvs.h"
  19. #include "fileattr.h"
  20. #include "edit.h"
  21.  
  22. int
  23. Checkin (type, finfo, rcs, rev, tag, options, message)
  24.     int type;
  25.     struct file_info *finfo;
  26.     char *rcs;
  27.     char *rev;
  28.     char *tag;
  29.     char *options;
  30.     char *message;
  31. {
  32.     char fname[PATH_MAX];
  33.     Vers_TS *vers;
  34.     int set_time;
  35.     char *rcscopy;
  36.     char *tocvsPath = NULL;
  37.  
  38.     (void) printf ("Checking in %s;\n", finfo->fullname);
  39.     (void) sprintf (fname, "%s/%s%s", CVSADM, CVSPREFIX, finfo->file);
  40.  
  41.     /* Make a copy of the RCS argument, in case it comes from
  42.        finfo->rcs which we might free in this routine.  */
  43.     rcscopy = xstrdup (rcs);
  44.  
  45.     /*
  46.      * Move the user file to a backup file, so as to preserve its
  47.      * modification times, then place a copy back in the original file name
  48.      * for the checkin and checkout.
  49.      */
  50.  
  51.     tocvsPath = wrap_tocvs_process_file (finfo->fullname);
  52.  
  53.     if (!noexec)
  54.     {
  55.         if (tocvsPath)
  56.     {
  57.             copy_file (tocvsPath, fname);
  58.         if (unlink_file_dir (finfo->file) < 0)
  59.         if (! existence_error (errno))
  60.             error (1, errno, "cannot remove %s", finfo->fullname);
  61.         copy_file (tocvsPath, finfo->file);
  62.     }
  63.     else
  64.     {
  65.         copy_file (finfo->file, fname);
  66.     }
  67.     }
  68.  
  69.     switch (RCS_checkin (rcscopy, NULL, message, rev, 0))
  70.     {
  71.     case 0:            /* everything normal */
  72.  
  73.         /*
  74.          * The checkin succeeded, so now check the new file back out and
  75.          * see if it matches exactly with the one we checked in. If it
  76.          * does, just move the original user file back, thus preserving
  77.          * the modes; otherwise, we have no recourse but to leave the
  78.          * newly checkout file as the user file and remove the old
  79.          * original user file.
  80.          */
  81.  
  82.         if (strcmp (options, "-V4") == 0) /* upgrade to V5 now */
  83.         options[0] = '\0';
  84.  
  85.         /* Reparse the RCS file, so that we can safely call
  86.                RCS_fast_checkout.  FIXME: We could probably calculate
  87.                all the changes.  */
  88.         freercsnode (&finfo->rcs);
  89.         finfo->rcs = RCS_parse (finfo->file, finfo->repository);
  90.  
  91.         /* FIXME: should be checking for errors.  */
  92.         (void) RCS_fast_checkout (finfo->rcs, "", rev, options, RUN_TTY,
  93.                       0);
  94.  
  95.         xchmod (finfo->file, 1);
  96.         if (xcmp (finfo->file, fname) == 0)
  97.         {
  98.         rename_file (fname, finfo->file);
  99.         /* the time was correct, so leave it alone */
  100.         set_time = 0;
  101.         }
  102.         else
  103.         {
  104.         if (unlink_file (fname) < 0)
  105.             error (0, errno, "cannot remove %s", fname);
  106.         /* sync up with the time from the RCS file */
  107.         set_time = 1;
  108.         }
  109.  
  110.         wrap_fromcvs_process_file (finfo->file);
  111.  
  112.         /*
  113.          * If we want read-only files, muck the permissions here, before
  114.          * getting the file time-stamp.
  115.          */
  116.         if (cvswrite == FALSE || fileattr_get (finfo->file, "_watched"))
  117.         xchmod (finfo->file, 0);
  118.  
  119.         /* Re-register with the new data.  */
  120.         vers = Version_TS (finfo, NULL, tag, NULL, 1, set_time);
  121.         if (strcmp (vers->options, "-V4") == 0)
  122.         vers->options[0] = '\0';
  123.         Register (finfo->entries, finfo->file, vers->vn_rcs, vers->ts_user,
  124.               vers->options, vers->tag, vers->date, (char *) 0);
  125.         history_write (type, NULL, vers->vn_rcs,
  126.                finfo->file, finfo->repository);
  127.  
  128.         if (tocvsPath)
  129.         if (unlink_file_dir (tocvsPath) < 0)
  130.             error (0, errno, "cannot remove %s", tocvsPath);
  131.  
  132.         break;
  133.  
  134.     case -1:            /* fork failed */
  135.         if (tocvsPath)
  136.         if (unlink_file_dir (tocvsPath) < 0)
  137.             error (0, errno, "cannot remove %s", tocvsPath);
  138.  
  139.         if (!noexec)
  140.         error (1, errno, "could not check in %s -- fork failed",
  141.                finfo->fullname);
  142.         free (rcscopy);
  143.         return (1);
  144.  
  145.     default:            /* ci failed */
  146.  
  147.         /*
  148.          * The checkin failed, for some unknown reason, so we restore the
  149.          * original user file, print an error, and return an error
  150.          */
  151.         if (tocvsPath)
  152.         if (unlink_file_dir (tocvsPath) < 0)
  153.             error (0, errno, "cannot remove %s", tocvsPath);
  154.  
  155.         if (!noexec)
  156.         {
  157.         rename_file (fname, finfo->file);
  158.         error (0, 0, "could not check in %s", finfo->fullname);
  159.         }
  160.         free (rcscopy);
  161.         return (1);
  162.     }
  163.  
  164.     /*
  165.      * When checking in a specific revision, we may have locked the wrong
  166.      * branch, so to be sure, we do an extra unlock here before
  167.      * returning.
  168.      */
  169.     if (rev)
  170.     {
  171.     (void) RCS_unlock (rcscopy, NULL, 1);
  172.     }
  173.  
  174.     free (rcscopy);
  175.  
  176. #ifdef SERVER_SUPPORT
  177.     if (server_active)
  178.     {
  179.     if (set_time)
  180.         /* Need to update the checked out file on the client side.  */
  181.         server_updated (finfo, vers, SERVER_UPDATED,
  182.                 NULL, NULL);
  183.     else
  184.         server_checked_in (finfo->file, finfo->update_dir, finfo->repository);
  185.     }
  186.     else
  187. #endif
  188.     mark_up_to_date (finfo->file);
  189.  
  190.     freevers_ts (&vers);
  191.     return (0);
  192. }
  193.