Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 17 Jul 2010 15:34:08 +0200
From:      joris dedieu <joris.dedieu@gmail.com>
To:        freebsd-hackers@freebsd.org
Subject:   [PATCH] allow empty files creation with install
Message-ID:  <AANLkTimMKTOUnUUAZKntuYneBcB9qPCORqDZMybMNWca@mail.gmail.com>

next in thread | raw e-mail | index | archive | help

[-- Attachment #1 --]
This patch add a -t switch to install(3). This is a small feature for
lazy sysadmins.

before :

touch /usr/home/foo/.history /usr/home/foo/.bash_history
chown foo /usr/home/foo/.history /usr/home/foo/.bash_history
chmod 600 /usr/home/foo/.history /usr/home/foo/.bash_history
chflags sappend /usr/home/foo/.history /usr/home/foo/.bash_history

after :

install -o foo -g foo -m 600 -f sappend /usr/home/foo/.history
/usr/home/foo/.bash_history


Regards,
Joris

[-- Attachment #2 --]
diff -Nur usr.bin/xinstall.orig/install.1 usr.bin/xinstall/install.1
--- usr.bin/xinstall.orig/install.1	2010-07-05 08:35:01.000000000 +0200
+++ usr.bin/xinstall/install.1	2010-07-17 14:59:40.127024519 +0200
@@ -62,6 +62,15 @@
 .Op Fl m Ar mode
 .Op Fl o Ar owner
 .Ar directory ...
+.Nm
+.Fl t
+.Op Fl v
+.Op Fl g Ar group
+.Op Fl f Ar flags
+.Op Fl m Ar mode
+.Op Fl o Ar owner
+.Ar file ...
+
 .Sh DESCRIPTION
 The file(s) are copied
 to the target file or directory.
@@ -112,6 +121,8 @@
 .It Fl d
 Create directories.
 Missing parent directories are created as required.
+.It Fl t
+Create an empty file
 .It Fl f
 Specify the target's file flags; see
 .Xr chflags 1
Files xinstall.orig/install.old and xinstall/install.old differ
diff -Nur usr.bin/xinstall.orig/xinstall.c usr.bin/xinstall/xinstall.c
--- usr.bin/xinstall.orig/xinstall.c	2010-07-05 08:35:01.000000000 +0200
+++ usr.bin/xinstall/xinstall.c	2010-07-17 14:59:15.181435253 +0200
@@ -82,7 +82,7 @@
 struct group *gp;
 gid_t gid;
 uid_t uid;
-int dobackup, docompare, dodir, dopreserve, dostrip, nommap, safecopy, verbose;
+int dobackup, docompare, dodir, dopreserve, dostrip, dofile, domode, nommap, safecopy, verbose;
 mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
 const char *suffix = BACKUP_SUFFIX;
 
@@ -94,6 +94,7 @@
 void	install_dir(char *);
 u_long	numeric_id(const char *, const char *);
 void	strip(const char *);
+void	touch_file(char *, u_int);
 int	trymmap(int);
 void	usage(void);
 
@@ -110,7 +111,7 @@
 
 	iflags = 0;
 	group = owner = NULL;
-	while ((ch = getopt(argc, argv, "B:bCcdf:g:Mm:o:pSsv")) != -1)
+	while ((ch = getopt(argc, argv, "B:bCcdf:g:Mm:o:pSstv")) != -1)
 		switch((char)ch) {
 		case 'B':
 			suffix = optarg;
@@ -140,6 +141,7 @@
 			nommap = 1;
 			break;
 		case 'm':
+			domode = 1;
 			if (!(set = setmode(optarg)))
 				errx(EX_USAGE, "invalid file mode: %s",
 				     optarg);
@@ -158,6 +160,9 @@
 		case 's':
 			dostrip = 1;
 			break;
+		case 't':
+			dofile = 1;
+			break;
 		case 'v':
 			verbose = 1;
 			break;
@@ -168,19 +173,27 @@
 	argc -= optind;
 	argv += optind;
 
-	/* some options make no sense when creating directories */
+	/* some options make no sense when creating directories or files */
 	if (dostrip && dodir) {
 		warnx("-d and -s may not be specified together");
 		usage();
 	}
+	if (dostrip && dofile) {
+		warnx("-t and -s may not be specified together");
+		usage();
+	}
+	if (dodir && dofile) {
+		warnx("-t and -d may not be specified together");
+		usage();
+	}
 
 	if (getenv("DONTSTRIP") != NULL) {
 		warnx("DONTSTRIP set - will not strip installed binaries");
 		dostrip = 0;
 	}
 
-	/* must have at least two arguments, except when creating directories */
-	if (argc == 0 || (argc == 1 && !dodir))
+	/* must have at least two arguments, except when creating files or directories */
+	if (argc == 0  || (argc == 1 && !(dodir || dofile)))
 		usage();
 
 	/* need to make a temp copy so we can compare stripped version */
@@ -211,6 +224,13 @@
 		/* NOTREACHED */
 	}
 
+	if (dofile) {
+		for (; *argv != NULL; ++argv)
+			touch_file(*argv, iflags);
+		exit(EX_OK);
+		/* NOTREACHED */
+	}
+
 	no_target = stat(to_name = argv[argc - 1], &to_sb);
 	if (!no_target && S_ISDIR(to_sb.st_mode)) {
 		for (; *argv != to_name; ++argv)
@@ -767,6 +787,47 @@
 }
 
 /*
+ * touch_file --
+ *	create an empty file
+ */
+void
+touch_file(char *path, u_int flags)
+{
+	struct stat sb;
+	int fd;
+	if (stat(path, &sb)) {
+		fd = open(path,  O_WRONLY | O_CREAT,
+			DEFFILEMODE);
+		if (fd < 0) 	
+			err(EX_OSERR, "touch %s", path);
+		else close(fd);
+	} else if (verbose)
+		(void)printf("install: touch %s\n", path);
+	else if (!S_ISREG(sb.st_mode))
+		errx(EX_OSERR, "%s exists but is not a regular file", path);
+	if ((gid != (gid_t)-1 || uid != (uid_t)-1) && chown(path, uid, gid))
+		warn("chown %u:%u %s", uid, gid, path);
+	/* Allow mode change on file but don't apply default mode which has exec
+	 * bit
+	 */
+	if (domode) {
+		if (chmod(path, mode))
+			warn("chmod %o %s", mode, path);
+	}
+	if (flags) {
+		if (chflags(path, flags) < 0) {
+			/* fs doesn't support flags */
+			if (errno == EOPNOTSUPP)
+				warn("%s: chflags", path);
+			else
+				err(EX_OSERR, "%s: chflags", path);
+		}
+	}
+
+}
+
+
+/*
  * usage --
  *	print a usage message and die
  */
@@ -778,7 +839,8 @@
 "               [-o owner] file1 file2\n"
 "       install [-bCcpSsv] [-B suffix] [-f flags] [-g group] [-m mode]\n"
 "               [-o owner] file1 ... fileN directory\n"
-"       install -d [-v] [-g group] [-m mode] [-o owner] directory ...\n");
+"       install -d [-v] [-g group] [-m mode] [-o owner] directory ...\n"
+"       install -t [-v] [-g group] [-f flags] [-m mode] [-o owner] file ...\n");
 	exit(EX_USAGE);
 	/* NOTREACHED */
 }

Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?AANLkTimMKTOUnUUAZKntuYneBcB9qPCORqDZMybMNWca>