bin/122271: [patch] usr.bin/xinstall - Add support for -D option
(create parent directories before installing file(s))
Ganael Laplanche
ganael.laplanche at martymac.com
Sun Mar 30 13:50:01 PDT 2008
>Number: 122271
>Category: bin
>Synopsis: [patch] usr.bin/xinstall - Add support for -D option (create parent directories before installing file(s))
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: change-request
>Submitter-Id: current-users
>Arrival-Date: Sun Mar 30 20:50:00 UTC 2008
>Closed-Date:
>Last-Modified:
>Originator: Ganael Laplanche
>Release: 7.0-STABLE
>Organization:
http://contribs.martymac.com
>Environment:
FreeBSD home.martymac.com 7.0-STABLE FreeBSD 7.0-STABLE #11: Tue Mar 25 14:32:03 CET 2008 root at home.martymac.com:/usr/obj/usr/src/sys/MYKERNEL amd64
>Description:
This patch enhances install by bringing support for automatically creating target directory's hierarchy before installing files (-D option).
examples :
install -D foo bar/
Will create directory bar/ and install foo inside.
install -D foo bar
Same behaviour as before : file foo is installed as bar
install -D foo bar baz/abc/
or
install -D foo bar baz/abc
Will create target directory baz/abc and install foo and bar inside.
install -d -D foo bar
Same behaviour as before : directories foo and bar are created
This options is inspired from gnu's install and may simplify porter's work.
I have updated documentation (install.1) to make the new option appear.
>How-To-Repeat:
>Fix:
Patch attached with submission follows:
diff -aur xinstall.orig/install.1 xinstall/install.1
--- xinstall.orig/install.1 2008-03-30 20:14:22.000000000 +0200
+++ xinstall/install.1 2008-03-30 22:29:24.000000000 +0200
@@ -40,7 +40,7 @@
.Nd install binaries
.Sh SYNOPSIS
.Nm
-.Op Fl bCcMpSsv
+.Op Fl bCcDMpSsv
.Op Fl B Ar suffix
.Op Fl f Ar flags
.Op Fl g Ar group
@@ -48,7 +48,7 @@
.Op Fl o Ar owner
.Ar file1 file2
.Nm
-.Op Fl bCcMpSsv
+.Op Fl bCcDMpSsv
.Op Fl B Ar suffix
.Op Fl f Ar flags
.Op Fl g Ar group
@@ -112,6 +112,9 @@
.It Fl d
Create directories.
Missing parent directories are created as required.
+.It Fl D
+If necessary, create target's parent directories before
+installing file(s).
.It Fl f
Specify the target's file flags; see
.Xr chflags 1
diff -aur xinstall.orig/xinstall.c xinstall/xinstall.c
--- xinstall.orig/xinstall.c 2008-03-30 20:14:22.000000000 +0200
+++ xinstall/xinstall.c 2008-03-30 22:16:14.000000000 +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, doparentdir, dodir, dopreserve, dostrip, nommap, safecopy, verbose;
mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
const char *suffix = BACKUP_SUFFIX;
@@ -92,6 +92,7 @@
int create_tempfile(const char *, char *, size_t);
void install(const char *, const char *, u_long, u_int);
void install_dir(char *);
+void install_parentdir(char *);
u_long numeric_id(const char *, const char *);
void strip(const char *);
int trymmap(int);
@@ -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:bCcDdf:g:Mm:o:pSsv")) != -1)
switch((char)ch) {
case 'B':
suffix = optarg;
@@ -124,6 +125,9 @@
case 'c':
/* For backwards compatibility. */
break;
+ case 'D':
+ doparentdir = 1;
+ break;
case 'd':
dodir = 1;
break;
@@ -211,6 +215,15 @@
/* NOTREACHED */
}
+ if (doparentdir) {
+ if(argc == 2) install_parentdir(argv[argc - 1]);
+ /*
+ * more than one file to install :
+ * destination has to be a directory
+ */
+ else install_dir(argv[argc - 1]);
+ }
+
no_target = stat(to_name = argv[argc - 1], &to_sb);
if (!no_target && S_ISDIR(to_sb.st_mode)) {
for (; *argv != to_name; ++argv)
@@ -219,8 +232,11 @@
/* NOTREACHED */
}
- /* can't do file1 file2 directory/file */
- if (argc != 2) {
+ /*
+ * can do file1 file2 directory/ only if parent
+ * directories have been created
+ */
+ if ((argc != 2) && (!doparentdir)) {
if (no_target)
warnx("target directory `%s' does not exist",
argv[argc - 1]);
@@ -767,6 +783,24 @@
}
/*
+ * install_parentdir --
+ * build directory hierarchy
+ * ignoring last non-directory part
+ */
+void
+install_parentdir(char *path)
+{
+ char parentpath[MAXPATHLEN];
+ char *p;
+
+ (void)strncpy(parentpath, path, MAXPATHLEN);
+ if ((p = strrchr(parentpath, '/')) != NULL) {
+ *p = '\0';
+ install_dir(parentpath);
+ }
+}
+
+/*
* usage --
* print a usage message and die
*/
@@ -774,9 +808,9 @@
usage()
{
(void)fprintf(stderr,
-"usage: install [-bCcpSsv] [-B suffix] [-f flags] [-g group] [-m mode]\n"
+"usage: install [-bCcDpSsv] [-B suffix] [-f flags] [-g group] [-m mode]\n"
" [-o owner] file1 file2\n"
-" install [-bCcpSsv] [-B suffix] [-f flags] [-g group] [-m mode]\n"
+" install [-bCcDpSsv] [-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");
exit(EX_USAGE);
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list