home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / prgramer / rcs / sources / checkin.c < prev    next >
C/C++ Source or Header  |  1992-02-23  |  4KB  |  148 lines

  1. #ifndef lint
  2. static char rcsid[] = "$Id: checkin.c,v 1.10 89/11/19 23:19:46 berliner Exp $";
  3. #endif 
  4.  
  5. /*
  6.  *    Copyright (c) 1989, Brian Berliner
  7.  *
  8.  *    You may distribute under the terms of the GNU General Public License
  9.  *    as specified in the README file that comes with the CVS 1.0 kit.
  10.  *
  11.  * Check In
  12.  *
  13.  *    Does a very careful checkin of the file "User", and tries not
  14.  *    to spoil its modification time (to avoid needless recompilations).
  15.  *    When RCS ID keywords get expanded on checkout, however, the
  16.  *    modification time is updated and there is no good way to get
  17.  *    around this.
  18.  *
  19.  *    Returns non-zero on error.
  20.  */
  21.  
  22. #include <ctype.h>
  23. #include "cvs.h"
  24.  
  25. Checkin(revision, message)
  26.     char *revision;
  27.     char *message;
  28. {
  29.     FILE *fp;
  30.     char fname[MAXPATHLEN];
  31.     char *tag;
  32.     int err = 0;
  33.  
  34.     /*
  35.      * The revision that is passed in includes the "-r" option
  36.      * as well as a numeric revision, otherwise it is a pointer
  37.      * to a null string.
  38.      */
  39.     if (revision[0] == '-')
  40.     tag = &revision[2];
  41.     else
  42.     tag = revision;
  43.     printf("Checking in %s;\n", User);
  44.     if (!use_editor)
  45.     printf("Log: %s\n", message);
  46.     (void) fflush(stdout);
  47.     (void) sprintf(Rcs, "%s%c%s%s", Repository, DIRSEP, User, RCSEXT);
  48.     (void) sprintf(fname, "%s%c%s%s", CVSADM, DIRSEP, CVSPREFIX, User);
  49.     /*
  50.      * Move the user file to a backup file, so as to preserve its
  51.      * modification times, then place a copy back in the original
  52.      * file name for the checkin and checkout.
  53.      */
  54.     rename_file(User, fname);
  55.     copy_file(fname, User);
  56.     (void) sprintf(prog, "%s -f %s %s", RCS_CI, revision, Rcs);
  57.     if ((fp = popen(prog, "w")) == NULL) {
  58.     err++;
  59.     } else {
  60.     (void) fprintf(fp, "%s", message);
  61.     err = pclose(fp);
  62.     }
  63.     if (err == 0) {
  64.     /*
  65.      * The checkin succeeded, so now check the new file back out
  66.      * and see if it matches exactly with the one we checked in.
  67.      * If it does, just move the original user file back, thus
  68.      * preserving the modes; otherwise, we have no recourse but
  69.      * to leave the newly checkout file as the user file and remove
  70.      * the old original user file.
  71.      */
  72.     (void) sprintf(prog, "%s -q %s %s", RCS_CO, revision, Rcs);
  73.     (void) system(prog);
  74.     xchmod(User, 1);        /* make it writable */
  75.     if (xcmp(User, fname) == 0)
  76.         rename_file(fname, User);
  77.     else
  78.         (void) unlink(fname);
  79.     /*
  80.      * If we want read-only files, muck the permissions here,
  81.      * before getting the user time-stamp.
  82.      */
  83.     if (cvswrite == FALSE) {
  84.         xchmod(User, 0);
  85.     }
  86.     Version_TS(Rcs, tag, User);
  87.     Register(User, VN_Rcs, TS_User);
  88.     } else {
  89.     /*
  90.      * The checkin failed, for some unknown reason, so we restore
  91.      * the original user file, print an error, try to unlock the
  92.      * (supposedly locked) RCS file, and try to restore
  93.      * any default branches, if they applied for this file.
  94.      */
  95.     rename_file(fname, User);
  96.     warn(0, "could not check in %s", User);
  97.     (void) sprintf(prog, "%s -u %s", RCS, Rcs);
  98.     if (system(prog) != 0)
  99.         warn(0, "could not UNlock %s", Rcs);
  100.     restore_branch();
  101.     return (1);
  102.     }
  103.     if (revision[0] != '\0') {
  104.     /*
  105.      * When checking in a specific revision, we may have locked the
  106.      * wrong branch, so to be sure, we do an extra unlock here
  107.      * before returning.
  108.      */
  109.     (void) sprintf(prog, "%s -q -u %s 2>%s", RCS, Rcs, DEVNULL);
  110.     (void) system(prog);
  111.     }
  112.     return (0);
  113. }
  114.  
  115. /*
  116.  * Called when the above checkin fails, because we may have to
  117.  * restore the default branch that existed before we attempted
  118.  * the checkin.
  119.  *
  120.  * Scan Blist for a match of the User file, and if it has a branch
  121.  * number tagged with it, do the "rcs -b" to set it back.
  122.  */
  123. static
  124. restore_branch()
  125. {
  126.     char blist[MAXLISTLEN];
  127.     char *cp, *user;
  128.  
  129.     (void) strcpy(blist, Blist);
  130.     while ((cp = index(blist, ':')) != NULL) {
  131.     user = cp;
  132.     /*
  133.      * The next line is safe because we "know" that
  134.      * Blist always starts with a space if it has entries.
  135.      */
  136.     while (!isspace(user[-1]))
  137.         user--;
  138.     *cp++ = '\0';
  139.     if (strcmp(User, user) == 0) {
  140.         (void) sprintf(prog, "%s -q -b%s %s", RCS, cp, Rcs);
  141.         if (system(prog) != 0)
  142.         warn(0, "cannot restore default branch %s for %s",
  143.              cp, Rcs);
  144.         return 0;
  145.     }
  146.     }
  147. }
  148.