[BACK]Return to ci.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / rcs

Diff for /src/usr.bin/rcs/ci.c between version 1.62 and 1.63

version 1.62, 2005/11/17 00:22:30 version 1.63, 2005/11/21 15:16:41
Line 49 
Line 49 
 #define DATE_MTIME      -2  #define DATE_MTIME      -2
   
 #define LOG_INIT        "Initial revision"  #define LOG_INIT        "Initial revision"
 #define LOG_PROMPT      "enter log message, terminated with a single '.' " \  #define LOG_PROMPT      "enter log message, terminated with a single '.' "    \
                         "or end of file:\n>> "                          "or end of file:\n>> "
 #define DESC_PROMPT     "enter description, terminated with single '.' "   \  #define DESC_PROMPT     "enter description, terminated with single '.' "      \
                         "or end of file:\nNOTE: This is NOT the log message!\n"                          "or end of file:\nNOTE: This is NOT the log message!" \
                           "\n>> "
   
 struct checkin_params {  struct checkin_params {
         int flags, openflags;          int flags, openflags;
Line 66 
Line 67 
   
 static int    checkin_attach_symbol(struct checkin_params *pb);  static int    checkin_attach_symbol(struct checkin_params *pb);
 static int    checkin_checklock(struct checkin_params *pb);  static int    checkin_checklock(struct checkin_params *pb);
   static char * checkin_choose_rcsfile(const char *);
 static char * checkin_diff_file(struct checkin_params *);  static char * checkin_diff_file(struct checkin_params *);
 static char * checkin_getdesc(void);  static char * checkin_getdesc(void);
 static char * checkin_getinput(const char *);  static char * checkin_getinput(const char *);
 static char * checkin_getlogmsg(RCSNUM *, RCSNUM *);  static char * checkin_getlogmsg(RCSNUM *, RCSNUM *);
 static void   checkin_init(struct checkin_params *);  static int    checkin_init(struct checkin_params *);
 static void   checkin_revert(struct checkin_params *pb);  
 static int    checkin_mtimedate(struct checkin_params *pb);  static int    checkin_mtimedate(struct checkin_params *pb);
   static int    checkin_update(struct checkin_params *pb);
   static void   checkin_revert(struct checkin_params *pb);
   
 void  void
 checkin_usage(void)  checkin_usage(void)
Line 96 
Line 99 
 checkin_main(int argc, char **argv)  checkin_main(int argc, char **argv)
 {  {
         int i, ch, status;          int i, ch, status;
         char  *filec;  
         struct stat sb;  
         struct checkin_params pb;          struct checkin_params pb;
         BUF *bp;  
   
         pb.date = DATE_NOW;          pb.date = DATE_NOW;
         pb.file = NULL;          pb.file = NULL;
Line 224 
Line 224 
   
         for (i = 0; i < argc; i++) {          for (i = 0; i < argc; i++) {
                 pb.filename = argv[i];                  pb.filename = argv[i];
                 if (rcs_statfile(pb.filename, pb.fpath, sizeof(pb.fpath)) < 0)  
                         continue;  
   
                 /*                  /*
                  * Test for existence of ,v file. If we are expected to                   * Test for existence of ,v file. If we are expected to
                  * create one, set NEWFILE flag.                   * create one, set NEWFILE flag.
                  */                   */
                 if ((pb.openflags & RCS_CREATE) && (stat(pb.fpath, &sb) < 0))                  if ((pb.openflags & RCS_CREATE)
                       && (rcs_statfile(pb.filename, pb.fpath,
                               sizeof(pb.fpath)) < 0))
                         pb.flags |= NEWFILE;                          pb.flags |= NEWFILE;
                 else                  else
                         pb.openflags &= ~RCS_CREATE;                          pb.openflags &= ~RCS_CREATE;
   
                   /*
                    * If we are to create a new ,v file, we must decide where it
                    * should go.
                    */
                   if (pb.flags & NEWFILE) {
                           char *fpath = checkin_choose_rcsfile(pb.filename);
                           if (fpath == NULL) {
                                   status = 1;
                                   continue;
                           }
                           strlcpy(pb.fpath, fpath, sizeof(pb.fpath));
                           free(fpath);
                   }
   
                 pb.file = rcs_open(pb.fpath, pb.openflags, pb.fmode);                  pb.file = rcs_open(pb.fpath, pb.openflags, pb.fmode);
   
                 if (pb.file == NULL) {                  if (pb.file == NULL) {
Line 246 
Line 260 
   
                 if (verbose == 1)                  if (verbose == 1)
                         printf("%s  <--  %s\n", pb.fpath, pb.filename);                          printf("%s  <--  %s\n", pb.fpath, pb.filename);
   
                 pb.frev = pb.file->rf_head;  
   
                 /*  
                  * If revision passed on command line is less than HEAD, bail.  
                  */  
                 if ((pb.newrev != NULL)  
                     && (rcsnum_cmp(pb.newrev, pb.frev, 0) > 0)) {  
                         cvs_log(LP_ERR, "revision is too low!");  
                         status = 1;  
                         rcs_close(pb.file);  
                         continue;  
                 }  
   
                 /*  
                  * Load file contents  
                  */  
                 if ((bp = cvs_buf_load(argv[i], BUF_AUTOEXT)) == NULL) {  
                         cvs_log(LP_ERR, "failed to load '%s'", pb.filename);  
                         exit(1);  
                 }  
   
                 if (cvs_buf_putc(bp, '\0') < 0)  
                         exit(1);  
   
                 filec = (char *)cvs_buf_release(bp);  
   
                 /*  
                  * Get RCS patch  
                  */  
                 if ((pb.deltatext = checkin_diff_file(&pb)) == NULL) {  
                         cvs_log(LP_ERR, "failed to get diff");  
                         exit(1);  
                 }  
   
                 /*  
                  * If -f is not specified and there are no differences, tell  
                  * the user and revert to latest version.  
                  */  
                 if (!(pb.flags & FORCE) && (strlen(pb.deltatext) < 1)) {  
                         checkin_revert(&pb);  
                         continue;  
                 }  
   
                 /*  
                  * Check for a lock belonging to this user. If none,  
                  * abort check-in.  
                  */  
                 if (checkin_checklock(&pb) < 0) {  
                         status = 1;  
                         continue;  
                 }  
   
                 /*  
                  * If no log message specified, get it interactively.  
                  */  
                 if (pb.flags & INTERACTIVE)  
                         pb.rcs_msg = checkin_getlogmsg(pb.frev, pb.newrev);  
   
                 /*  
                  * Remove the lock  
                  */  
                 if (rcs_lock_remove(pb.file, pb.frev) < 0) {  
                         if (rcs_errno != RCS_ERR_NOENT)  
                             cvs_log(LP_WARN, "failed to remove lock");  
                 }  
   
                 /*  
                  * Current head revision gets the RCS patch as rd_text  
                  */  
                 if (rcs_deltatext_set(pb.file, pb.frev, pb.deltatext) == -1) {  
                         cvs_log(LP_ERR,  
                             "failed to set new rd_text for head rev");  
                         exit (1);  
                 }  
   
                 /*  
                  * Set the date of the revision to be the last modification  
                  * time of the working file if -d has no argument.  
                  */  
                 if (pb.date == DATE_MTIME  
                     && (checkin_mtimedate(&pb) < 0))  
                             continue;  
   
                   if (pb.flags & NEWFILE)
                 /*                          status = checkin_init(&pb);
                  * Now add our new revision  
                  */  
                 if (rcs_rev_add(pb.file,  
                         (pb.newrev == NULL ? RCS_HEAD_REV : pb.newrev),  
                     pb.rcs_msg, pb.date, pb.username) != 0) {  
                         cvs_log(LP_ERR, "failed to add new revision");  
                         exit(1);  
                 }  
   
                 /*  
                  * If we are checking in to a non-default (ie user-specified)  
                  * revision, set head to this revision.  
                  */  
                 if (pb.newrev != NULL)  
                         rcs_head_set(pb.file, pb.newrev);  
                 else                  else
                         pb.newrev = pb.file->rf_head;                          status = checkin_update(&pb);
   
                 /*  
                  * New head revision has to contain entire file;  
                  */  
                 if (rcs_deltatext_set(pb.file, pb.frev, filec) == -1) {  
                         cvs_log(LP_ERR, "failed to set new head revision");  
                         exit(1);  
                 }  
   
                 /*  
                  * Attach a symbolic name to this revision if specified.  
                  */  
                 if (pb.symbol != NULL  
                     && (checkin_attach_symbol(&pb) < 0)) {  
                         status = 1;  
                         continue;  
                 }  
   
                 /*  
                  * Set the state of this revision if specified.  
                  */  
                 if (pb.state != NULL)  
                         (void)rcs_state_set(pb.file, pb.newrev, pb.state);  
   
                 free(pb.deltatext);  
                 free(filec);  
                 (void)unlink(pb.filename);  
   
                 /*  
                  * Do checkout if -u or -l are specified.  
                  */  
                 if (((pb.flags & CO_LOCK) || (pb.flags & CO_UNLOCK))  
                     && !(pb.flags & CI_DEFAULT))  
                         checkout_rev(pb.file, pb.newrev, pb.filename, pb.flags,  
                             pb.username);  
   
                 /* File will NOW be synced */  
                 rcs_close(pb.file);  
   
                 if (pb.flags & INTERACTIVE) {  
                         free(pb.rcs_msg);  
                         pb.rcs_msg = NULL;  
                 }  
         }          }
   
         return (status);          return (status);
Line 539 
Line 412 
 }  }
   
 /*  /*
    * checkin_update()
    *
    * Do a checkin to an existing RCS file.
    *
    * On success, return 0. On error return -1.
    */
   static int
   checkin_update(struct checkin_params *pb)
   {
           char  *filec;
           BUF *bp;
   
           pb->frev = pb->file->rf_head;
   
           /*
            * If revision passed on command line is less than HEAD, bail.
            */
           if ((pb->newrev != NULL)
               && (rcsnum_cmp(pb->newrev, pb->frev, 0) > 0)) {
                   cvs_log(LP_ERR, "revision is too low!");
                   rcs_close(pb->file);
                   return (-1);
           }
   
           /*
            * Load file contents
            */
           if ((bp = cvs_buf_load(pb->filename, BUF_AUTOEXT)) == NULL) {
                   cvs_log(LP_ERR, "failed to load '%s'", pb->filename);
                   return (-1);
           }
   
           if (cvs_buf_putc(bp, '\0') < 0)
                   return (-1);
   
           filec = (char *)cvs_buf_release(bp);
   
           /*
            * Get RCS patch
            */
           if ((pb->deltatext = checkin_diff_file(pb)) == NULL) {
                   cvs_log(LP_ERR, "failed to get diff");
                   return (-1);
           }
   
           /*
            * If -f is not specified and there are no differences, tell
            * the user and revert to latest version.
            */
           if (!(pb->flags & FORCE) && (strlen(pb->deltatext) < 1)) {
                   checkin_revert(pb);
                   return (0);
           }
   
           /*
            * Check for a lock belonging to this user. If none,
            * abort check-in.
            */
           if (checkin_checklock(pb) < 0)
                   return (-1);
   
           /*
            * If no log message specified, get it interactively.
            */
           if (pb->flags & INTERACTIVE)
                   pb->rcs_msg = checkin_getlogmsg(pb->frev, pb->newrev);
   
           /*
            * Remove the lock
            */
           if (rcs_lock_remove(pb->file, pb->frev) < 0) {
                   if (rcs_errno != RCS_ERR_NOENT)
                       cvs_log(LP_WARN, "failed to remove lock");
           }
   
           /*
            * Current head revision gets the RCS patch as rd_text
            */
           if (rcs_deltatext_set(pb->file, pb->frev, pb->deltatext) == -1) {
                   cvs_log(LP_ERR,
                       "failed to set new rd_text for head rev");
                   exit (1);
           }
   
           /*
            * Set the date of the revision to be the last modification
            * time of the working file if -d has no argument.
            */
           if (pb->date == DATE_MTIME
               && (checkin_mtimedate(pb) < 0))
                   return (-1);
   
           /*
            * Now add our new revision
            */
           if (rcs_rev_add(pb->file,
               (pb->newrev == NULL ? RCS_HEAD_REV : pb->newrev),
               pb->rcs_msg, pb->date, pb->username) != 0) {
                   cvs_log(LP_ERR, "failed to add new revision");
                   return (-1);
           }
   
           /*
            * If we are checking in to a non-default (ie user-specified)
            * revision, set head to this revision.
            */
           if (pb->newrev != NULL)
                   rcs_head_set(pb->file, pb->newrev);
           else
                   pb->newrev = pb->file->rf_head;
   
           /*
            * New head revision has to contain entire file;
            */
   
           if (rcs_deltatext_set(pb->file, pb->frev, filec) == -1) {
                   cvs_log(LP_ERR, "failed to set new head revision");
                   exit(1);
           }
   
           /*
            * Attach a symbolic name to this revision if specified.
            */
           if (pb->symbol != NULL
               && (checkin_attach_symbol(pb) < 0))
                   return (-1);
   
           /*
            * Set the state of this revision if specified.
            */
           if (pb->state != NULL)
                   (void)rcs_state_set(pb->file, pb->newrev, pb->state);
   
           free(pb->deltatext);
           free(filec);
           (void)unlink(pb->filename);
   
           /*
            * Do checkout if -u or -l are specified.
            */
           if (((pb->flags & CO_LOCK) || (pb->flags & CO_UNLOCK))
               && !(pb->flags & CI_DEFAULT))
                   checkout_rev(pb->file, pb->newrev, pb->filename, pb->flags,
                       pb->username);
   
           /* File will NOW be synced */
           rcs_close(pb->file);
   
           if (pb->flags & INTERACTIVE) {
                   free(pb->rcs_msg);
                   pb->rcs_msg = NULL;
           }
           return (0);
   }
   
   /*
  * checkin_init()   * checkin_init()
  *   *
  * Does an initial check in, just enough to create the new ,v file   * Does an initial check in, just enough to create the new ,v file
  * XXX not fully implemented yet.   * XXX not fully implemented yet.
    * On success, return 0. On error return -1.
  */   */
 static void  static int
 checkin_init(struct checkin_params *pb)  checkin_init(struct checkin_params *pb)
 {  {
         BUF *bp;          BUF *bp;
Line 555 
Line 585 
          */           */
         if ((bp = cvs_buf_load(pb->filename, BUF_AUTOEXT)) == NULL) {          if ((bp = cvs_buf_load(pb->filename, BUF_AUTOEXT)) == NULL) {
                 cvs_log(LP_ERR, "failed to load '%s'", pb->filename);                  cvs_log(LP_ERR, "failed to load '%s'", pb->filename);
                 exit(1);                  return (-1);
         }          }
   
         if (cvs_buf_putc(bp, '\0') < 0)          if (cvs_buf_putc(bp, '\0') < 0)
                 exit(1);                  return (-1);
   
         filec = (char *)cvs_buf_release(bp);          filec = (char *)cvs_buf_release(bp);
   
Line 568 
Line 598 
          */           */
         rcs_desc = checkin_getdesc();          rcs_desc = checkin_getdesc();
         rcs_desc_set(pb->file, rcs_desc);          rcs_desc_set(pb->file, rcs_desc);
           printf("set description\n");
   
         /*          /*
          * Now add our new revision           * Now add our new revision
          */           */
         if (rcs_rev_add(pb->file, RCS_HEAD_REV, LOG_INIT,          if (rcs_rev_add(pb->file, RCS_HEAD_REV, LOG_INIT,
                 -1, pb->username) != 0) {              -1, pb->username) != 0) {
                 cvs_log(LP_ERR, "failed to add new revision");                  cvs_log(LP_ERR, "failed to add new revision");
                 exit(1);                  return (-1);
         }          }
           printf("added rev\n");
           /*
            * If we are checking in to a non-default (ie user-specified)
            * revision, set head to this revision.
            */
           if (pb->newrev != NULL)
                   rcs_head_set(pb->file, pb->newrev);
           else
                   pb->newrev = pb->file->rf_head;
           printf("set head rev\n");
   
           /*
            * New head revision has to contain entire file;
            */
           if (rcs_deltatext_set(pb->file, pb->frev, filec) == -1) {
                   cvs_log(LP_ERR, "failed to set new head revision");
                   return (-1);
           }
           printf("set delta text\n");
   
           return (0);
 }  }
   
 /*  /*
Line 692 
Line 744 
         }          }
         pb->date = (time_t)sb.st_mtimespec.tv_sec;          pb->date = (time_t)sb.st_mtimespec.tv_sec;
         return (0);          return (0);
   }
   
   /*
    * checkin_rcsfile()
    *
    * Given a relative filename, decide where the corresponding ,v file
    * should be.
    *
    * Returns pointer to a char array on success, NULL on failure.
    */
   static char *
   checkin_choose_rcsfile(const char *filename)
   {
           char fullpath[MAXPATHLEN], *basepath;
           size_t len;
           struct stat sb;
   
           if (realpath(filename, fullpath) == NULL) {
                   cvs_log(LP_ERRNO, "realpath failed: `%s'", filename);
                   return (NULL);
           }
           len = strlen(fullpath);
           while (fullpath[len] != '/')
                   len--;
           if (len > 0) {
                   /*
                    * Need two bytes extra for trailing slash and
                    * NUL-termination.
                    */
                   len += 2;
                   if ((basepath = malloc(MAXPATHLEN)) == NULL) {
                           cvs_log(LP_ERRNO, "could not allocate memory");
                           return (NULL);
                   }
                   strlcpy(basepath, fullpath, len);
                   strlcat(basepath, RCSDIR"/", MAXPATHLEN);
                   if ((stat(basepath, &sb) == 0) && (sb.st_mode & S_IFDIR)) {
                           /* <path>/RCS/<filename>,v */
                           strlcat(basepath, filename, MAXPATHLEN);
                           strlcat(basepath, RCS_FILE_EXT, MAXPATHLEN);
                   } else {
                           /* <path>/<filename>,v */
                           bzero(basepath, MAXPATHLEN);
                           strlcpy(basepath, fullpath, len);
                           strlcat(basepath, filename, MAXPATHLEN);
                           strlcat(basepath, RCS_FILE_EXT, MAXPATHLEN);
                   }
                   return (basepath);
           } else
                   return (NULL);
 }  }

Legend:
Removed from v.1.62  
changed lines
  Added in v.1.63