Re: Comments on the pax patch?
On Wed, 2011-10-12 at 23:24 +0200, Guillem Jover wrote:
> On Wed, 2011-10-12 at 21:03:13 +0200, Svante Signell wrote:
> > Attached is a patch to make pax-20090728 build under GNU/Hurd. Function
> > calls changed are readlink()->xreadlink() (new, same as for psmisc) and
>
> The same comment here, I've mentioned before the lstat/malloc/readlink
> combo before. I even sent a patch to the man-pages upstream to
> document it, now merged, please see:
>
> <http://man7.org/linux/man-pages/online/pages/man2/readlink.2.html>
>
> > realpath()->canonicalize_file_name().
>
> Does the code only support GNU based systems? Otherwise this cannot be
Attached is an updated patch using the already existing lstat call and
conditioning on __GNU__ for canonicalize_file_name. I hope I got the
free() calls at the right places.
Any thing left before submitting a bug report?
diff -ur pax-20090728/file_subs.c pax-20090728.modified/file_subs.c
--- pax-20090728/file_subs.c 2009-07-28 17:38:28.000000000 +0000
+++ pax-20090728.modified/file_subs.c 2011-10-13 14:02:04.000000000 +0000
@@ -351,7 +351,7 @@
int pass = 0;
mode_t file_mode;
struct stat sb;
- char target[MAXPATHLEN];
+ char *target = NULL;
char *nm = arcn->name;
int len;
@@ -374,8 +374,15 @@
if (strcmp(NM_TAR, argv0) == 0 && Lflag) {
while (lstat(nm, &sb) == 0 &&
S_ISLNK(sb.st_mode)) {
+ target = malloc(sb.st_size + 1);
+ if (target == NULL) {
+ oerrno = ENOMEM;
+ syswarn(1, oerrno,
+ "Insufficient memory");
+ return(-1);
+ }
len = readlink(nm, target,
- sizeof target - 1);
+ strlen(target));
if (len == -1) {
syswarn(0, errno,
"cannot follow symlink %s in chain for %s",
@@ -388,6 +395,7 @@
}
}
res = mkdir(nm, file_mode);
+ free(target);
badlink:
if (ign)
diff -ur pax-20090728/tables.c pax-20090728.modified/tables.c
--- pax-20090728/tables.c 2009-07-28 17:38:28.000000000 +0000
+++ pax-20090728.modified/tables.c 2011-10-13 13:40:37.000000000 +0000
@@ -1126,13 +1126,21 @@
add_dir(char *name, struct stat *psb, int frc_mode)
{
DIRDATA *dblk;
+#ifdef __GNU__
+ char *rp;
+#else
char realname[MAXPATHLEN], *rp;
+#endif
if (dirp == NULL)
return;
if (havechd && *name != '/') {
+#ifdef __GNU__
+ if ((rp = canonicalize_file_name(name)) == NULL) {
+#else
if ((rp = realpath(name, realname)) == NULL) {
+#endif
paxwarn(1, "Cannot canonicalize %s", name);
return;
}
@@ -1143,6 +1151,9 @@
if (dblk == NULL) {
paxwarn(1, "Unable to store mode and times for created"
" directory: %s", name);
+#ifdef __GNU__
+ free(rp);
+#endif
return;
}
dirp = dblk;
@@ -1152,6 +1163,9 @@
if ((dblk->name = strdup(name)) == NULL) {
paxwarn(1, "Unable to store mode and times for created"
" directory: %s", name);
+#ifdef __GNU__
+ free(rp);
+#endif
return;
}
dblk->mode = psb->st_mode & 0xffff;
@@ -1159,6 +1173,9 @@
dblk->atime = psb->st_atime;
dblk->frc_mode = frc_mode;
++dircnt;
+#ifdef __GNU__
+ free(rp);
+#endif
}
/*
Reply to: