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

Diff for /src/usr.bin/cvs/rcs.c between version 1.206 and 1.207

version 1.206, 2007/01/26 21:59:11 version 1.207, 2007/02/01 20:36:21
Line 215 
Line 215 
 int rcs_errno = RCS_ERR_NOERR;  int rcs_errno = RCS_ERR_NOERR;
   
 int             rcs_patch_lines(struct cvs_lines *, struct cvs_lines *);  int             rcs_patch_lines(struct cvs_lines *, struct cvs_lines *);
 static int      rcs_movefile(char *, char *, mode_t, u_int);  
 static void     rcs_parse_init(RCSFILE *);  static void     rcs_parse_init(RCSFILE *);
 static int      rcs_parse_admin(RCSFILE *);  static int      rcs_parse_admin(RCSFILE *);
 static int      rcs_parse_delta(RCSFILE *);  static int      rcs_parse_delta(RCSFILE *);
Line 361 
Line 360 
 rcs_write(RCSFILE *rfp)  rcs_write(RCSFILE *rfp)
 {  {
         FILE *fp;          FILE *fp;
         char buf[1024], numbuf[64], *fn;          char buf[1024], numbuf[64], *fn, tmpdir[MAXPATHLEN];
         struct rcs_access *ap;          struct rcs_access *ap;
         struct rcs_sym *symp;          struct rcs_sym *symp;
         struct rcs_branch *brp;          struct rcs_branch *brp;
         struct rcs_delta *rdp;          struct rcs_delta *rdp;
         struct rcs_lock *lkp;          struct rcs_lock *lkp;
         size_t len;          size_t len;
         int fd, from_fd, to_fd;          int fd, saved_errno;
   
         from_fd = to_fd = fd = -1;          fd = -1;
   
         if (rfp->rf_flags & RCS_SYNCED)          if (rfp->rf_flags & RCS_SYNCED)
                 return;                  return;
Line 381 
Line 380 
         /* Write operations need the whole file parsed */          /* Write operations need the whole file parsed */
         rcs_parse_deltatexts(rfp, NULL);          rcs_parse_deltatexts(rfp, NULL);
   
         (void)xasprintf(&fn, "%s/rcs.XXXXXXXXXX", cvs_tmpdir);          if (strlcpy(tmpdir, rfp->rf_path, sizeof(tmpdir)) >= sizeof(tmpdir))
                   fatal("rcs_write: truncation");
           (void)xasprintf(&fn, "%s/rcs.XXXXXXXXXX", dirname(tmpdir));
   
         if ((fd = mkstemp(fn)) == -1)          if ((fd = mkstemp(fn)) == -1)
                 fatal("%s", fn);                  fatal("%s", fn);
   
         if ((fp = fdopen(fd, "w+")) == NULL) {          if ((fp = fdopen(fd, "w")) == NULL) {
                 int saved_errno;  
   
                 saved_errno = errno;                  saved_errno = errno;
                 (void)unlink(fn);                  (void)unlink(fn);
                 errno = saved_errno;                  fatal("fdopen %s: %s", fn, strerror(saved_errno));
                 fatal("%s", fn);  
         }          }
   
         if (rfp->rf_head != NULL)          if (rfp->rf_head != NULL)
Line 497 
Line 495 
                 }                  }
                 fputs("@\n", fp);                  fputs("@\n", fp);
         }          }
           if (fchmod(fd, rfp->rf_mode) == -1) {
                   saved_errno = errno;
                   (void)unlink(fn);
                   fatal("fchmod %s: %s", fn, strerror(saved_errno));
           }
   
         (void)fclose(fp);          (void)fclose(fp);
   
         if (rcs_movefile(fn, rfp->rf_path, rfp->rf_mode, rfp->rf_flags) == -1) {          if (rename(fn, rfp->rf_path) == -1) {
                   saved_errno = errno;
                 (void)unlink(fn);                  (void)unlink(fn);
                 fatal("rcs_movefile failed");                  fatal("rename(%s, %s): %s", fn, rfp->rf_path,
                       strerror(saved_errno));
         }          }
   
         rfp->rf_flags |= RCS_SYNCED;          rfp->rf_flags |= RCS_SYNCED;
   
         if (fn != NULL)          if (fn != NULL)
                 xfree(fn);                  xfree(fn);
 }  
   
 /*  
  * rcs_movefile()  
  *  
  * Move a file using rename(2) if possible and copying if not.  
  * Returns 0 on success, -1 on failure.  
  */  
 static int  
 rcs_movefile(char *from, char *to, mode_t perm, u_int to_flags)  
 {  
         FILE *src, *dst;  
         size_t nread, nwritten;  
         char buf[MAXBSIZE];  
         int ret;  
   
         ret = -1;  
   
         if (rename(from, to) == 0) {  
                 if (chmod(to, perm) == -1) {  
                         cvs_log(LP_ERRNO, "%s", to);  
                         return (-1);  
                 }  
                 return (0);  
         } else if (errno != EXDEV) {  
                 cvs_log(LP_NOTICE, "failed to access temp RCS output file");  
                 return (-1);  
         }  
   
         if ((chmod(to, S_IWUSR) == -1) && !(to_flags & RCS_CREATE)) {  
                 cvs_log(LP_ERR, "chmod(%s, 0%o) failed", to, S_IWUSR);  
                 return (-1);  
         }  
   
         /* different filesystem, have to copy the file */  
         if ((src = fopen(from, "r")) == NULL) {  
                 cvs_log(LP_ERRNO, "%s", from);  
                 return (-1);  
         }  
         if ((dst = fopen(to, "w")) == NULL) {  
                 cvs_log(LP_ERRNO, "%s", to);  
                 return (-1);  
         }  
         if (fchmod(fileno(dst), perm)) {  
                 cvs_log(LP_ERR, "%s", to);  
                 (void)unlink(to);  
                 return (-1);  
         }  
   
         while ((nread = fread(buf, sizeof(char), MAXBSIZE, src)) != 0) {  
                 if (ferror(src)) {  
                         cvs_log(LP_ERRNO, "failed to read `%s'", from);  
                         (void)unlink(to);  
                         goto out;  
                 }  
                 nwritten = fwrite(buf, sizeof(char), nread, dst);  
                 if (nwritten != nread) {  
                         cvs_log(LP_ERRNO, "failed to write `%s'", to);  
                         (void)unlink(to);  
                         goto out;  
                 }  
         }  
   
         (void)unlink(from);  
         ret = 0;  
   
 out:  
         (void)fclose(src);  
         (void)fclose(dst);  
   
         return (ret);  
 }  }
   
 /*  /*

Legend:
Removed from v.1.206  
changed lines
  Added in v.1.207