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

Diff for /src/usr.bin/xinstall/xinstall.c between version 1.67 and 1.68

version 1.67, 2018/09/16 02:44:07 version 1.68, 2019/02/08 12:53:44
Line 60 
Line 60 
 #define NOCHANGEBITS    (UF_IMMUTABLE | UF_APPEND | SF_IMMUTABLE | SF_APPEND)  #define NOCHANGEBITS    (UF_IMMUTABLE | UF_APPEND | SF_IMMUTABLE | SF_APPEND)
 #define BACKUP_SUFFIX   ".old"  #define BACKUP_SUFFIX   ".old"
   
 int dobackup, docompare, dodest, dodir, dopreserve, dostrip, safecopy;  int dobackup, docompare, dodest, dodir, dopreserve, dostrip;
 int mode = S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH;  int mode = S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH;
 char pathbuf[PATH_MAX], tempfile[PATH_MAX];  char pathbuf[PATH_MAX], tempfile[PATH_MAX];
 char *suffix = BACKUP_SUFFIX;  char *suffix = BACKUP_SUFFIX;
Line 73 
Line 73 
 void    install_dir(char *, int);  void    install_dir(char *, int);
 void    strip(char *);  void    strip(char *);
 void    usage(void);  void    usage(void);
 int     create_newfile(char *, struct stat *);  
 int     create_tempfile(char *, char *, size_t);  int     create_tempfile(char *, char *, size_t);
 int     file_write(int, char *, size_t, int *, int *, int);  int     file_write(int, char *, size_t, int *, int *, int);
 void    file_flush(int, int);  void    file_flush(int, int);
Line 129 
Line 128 
                         docompare = dopreserve = 1;                          docompare = dopreserve = 1;
                         break;                          break;
                 case 'S':                  case 'S':
                         safecopy = 1;                          /* For backwards compatibility. */
                         break;                          break;
                 case 's':                  case 's':
                         dostrip = 1;                          dostrip = 1;
Line 148 
Line 147 
         argv += optind;          argv += optind;
   
         /* some options make no sense when creating directories */          /* some options make no sense when creating directories */
         if ((safecopy || docompare || dostrip) && dodir)          if ((docompare || dostrip) && dodir)
                 usage();                  usage();
   
         /* must have at least two arguments, except when creating directories */          /* must have at least two arguments, except when creating directories */
         if (argc < 2 && !dodir)          if (argc < 2 && !dodir)
                 usage();                  usage();
   
         /* need to make a temp copy so we can compare stripped version */  
         if (docompare && dostrip)  
                 safecopy = 1;  
   
         /* get group and owner id's */          /* get group and owner id's */
         if (group != NULL && gid_from_group(group, &gid) == -1) {          if (group != NULL && gid_from_group(group, &gid) == -1) {
                 gid = strtonum(group, 0, GID_MAX, &errstr);                  gid = strtonum(group, 0, GID_MAX, &errstr);
Line 265 
Line 260 
                         err(1, "%s", from_name);                          err(1, "%s", from_name);
         }          }
   
         if (safecopy) {          to_fd = create_tempfile(to_name, tempfile, sizeof(tempfile));
                 to_fd = create_tempfile(to_name, tempfile, sizeof(tempfile));          if (to_fd < 0)
                 if (to_fd < 0)                  err(1, "%s", tempfile);
                         err(1, "%s", tempfile);  
         } else if (docompare && !dostrip) {  
                 if ((to_fd = open(to_name, O_RDONLY, 0)) < 0)  
                         err(1, "%s", to_name);  
         } else {  
                 if ((to_fd = create_newfile(to_name, &to_sb)) < 0)  
                         err(1, "%s", to_name);  
         }  
   
         if (!devnull) {          if (!devnull)
                 if (docompare && !safecopy) {                  copy(from_fd, from_name, to_fd, tempfile, from_sb.st_size,
                         files_match = !(compare(from_fd, from_name,                      ((off_t)from_sb.st_blocks * S_BLKSIZE < from_sb.st_size));
                                         from_sb.st_size, to_fd,  
                                         to_name, to_sb.st_size));  
   
                         /* Truncate "to" file for copy unless we match */  
                         if (!files_match) {  
                                 (void)close(to_fd);  
                                 if ((to_fd = create_newfile(to_name, &to_sb)) < 0)  
                                         err(1, "%s", to_name);  
                         }  
                 }  
                 if (!files_match)  
                         copy(from_fd, from_name, to_fd,  
                              safecopy ? tempfile : to_name, from_sb.st_size,  
                              ((off_t)from_sb.st_blocks * S_BLKSIZE < from_sb.st_size));  
         }  
   
         if (dostrip) {          if (dostrip) {
                 strip(safecopy ? tempfile : to_name);                  strip(tempfile);
   
                 /*                  /*
                  * Re-open our fd on the target, in case we used a strip                   * Re-open our fd on the target, in case we used a strip
                  *  that does not work in-place -- like gnu binutils strip.                   *  that does not work in-place -- like gnu binutils strip.
                  */                   */
                 close(to_fd);                  close(to_fd);
                 if ((to_fd = open(safecopy ? tempfile : to_name, O_RDONLY,                  if ((to_fd = open(tempfile, O_RDONLY, 0)) < 0)
                      0)) < 0)  
                         err(1, "stripping %s", to_name);                          err(1, "stripping %s", to_name);
         }          }
   
         /*          /*
          * Compare the (possibly stripped) temp file to the target.           * Compare the (possibly stripped) temp file to the target.
          */           */
         if (safecopy && docompare) {          if (docompare) {
                 int temp_fd = to_fd;                  int temp_fd = to_fd;
                 struct stat temp_sb;                  struct stat temp_sb;
   
Line 362 
Line 333 
         if ((gid != (gid_t)-1 || uid != (uid_t)-1) &&          if ((gid != (gid_t)-1 || uid != (uid_t)-1) &&
             fchown(to_fd, uid, gid)) {              fchown(to_fd, uid, gid)) {
                 serrno = errno;                  serrno = errno;
                 (void)unlink(safecopy ? tempfile : to_name);                  (void)unlink(tempfile);
                 errx(1, "%s: chown/chgrp: %s",                  errx(1, "%s: chown/chgrp: %s", tempfile, strerror(serrno));
                     safecopy ? tempfile : to_name, strerror(serrno));  
         }          }
         if (fchmod(to_fd, mode)) {          if (fchmod(to_fd, mode)) {
                 serrno = errno;                  serrno = errno;
                 (void)unlink(safecopy ? tempfile : to_name);                  (void)unlink(tempfile);
                 errx(1, "%s: chmod: %s", safecopy ? tempfile : to_name,                  errx(1, "%s: chmod: %s", tempfile, strerror(serrno));
                     strerror(serrno));  
         }          }
   
         /*          /*
Line 380 
Line 349 
         if (fchflags(to_fd,          if (fchflags(to_fd,
             flags & SETFLAGS ? fset : from_sb.st_flags & ~UF_NODUMP)) {              flags & SETFLAGS ? fset : from_sb.st_flags & ~UF_NODUMP)) {
                 if (errno != EOPNOTSUPP || (from_sb.st_flags & ~UF_NODUMP) != 0)                  if (errno != EOPNOTSUPP || (from_sb.st_flags & ~UF_NODUMP) != 0)
                         warnx("%s: chflags: %s",                          warnx("%s: chflags: %s", tempfile, strerror(errno));
                             safecopy ? tempfile :to_name, strerror(errno));  
         }          }
   
         if (flags & USEFSYNC)          if (flags & USEFSYNC)
Line 391 
Line 359 
                 (void)close(from_fd);                  (void)close(from_fd);
   
         /*          /*
          * Move the new file into place if doing a safe copy           * Move the new file into place if the files are different
          * and the files are different (or just not compared).           * or were not compared.
          */           */
         if (safecopy && !files_match) {          if (!files_match) {
                 /* Try to turn off the immutable bits. */                  /* Try to turn off the immutable bits. */
                 if (to_sb.st_flags & (NOCHANGEBITS))                  if (to_sb.st_flags & (NOCHANGEBITS))
                         (void)chflags(to_name, to_sb.st_flags & ~(NOCHANGEBITS));                          (void)chflags(to_name, to_sb.st_flags & ~(NOCHANGEBITS));
Line 655 
Line 623 
         strlcat(p, "INS@XXXXXXXXXX", tsize);          strlcat(p, "INS@XXXXXXXXXX", tsize);
   
         return(mkstemp(temp));          return(mkstemp(temp));
 }  
   
 /*  
  * create_newfile --  
  *      create a new file, overwriting an existing one if necessary  
  */  
 int  
 create_newfile(char *path, struct stat *sbp)  
 {  
         char backup[PATH_MAX];  
   
         /*  
          * Unlink now... avoid ETXTBSY errors later.  Try and turn  
          * off the append/immutable bits -- if we fail, go ahead,  
          * it might work.  
          */  
         if (sbp->st_flags & (NOCHANGEBITS))  
                 (void)chflags(path, sbp->st_flags & ~(NOCHANGEBITS));  
   
         if (dobackup) {  
                 (void)snprintf(backup, PATH_MAX, "%s%s", path, suffix);  
                 /* It is ok for the target file not to exist. */  
                 if (rename(path, backup) < 0 && errno != ENOENT)  
                         err(1, "rename: %s to %s (errno %d)", path, backup, errno);  
         } else {  
                 if (unlink(path) < 0 && errno != ENOENT)  
                         err(1, "%s", path);  
         }  
   
         return(open(path, O_CREAT | O_RDWR | O_EXCL, S_IRUSR | S_IWUSR));  
 }  }
   
 /*  /*

Legend:
Removed from v.1.67  
changed lines
  Added in v.1.68