[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Building sharutils 4.13.4 with MinGW
From: |
Eli Zaretskii |
Subject: |
Building sharutils 4.13.4 with MinGW |
Date: |
Sun, 07 Apr 2013 20:12:18 +0300 |
I've built this distribution with MinGW tools on MS-Windows. Quite
unexpectedly for such a veteran package, it turned out to be an uphill
battle.
In addition to MinGW-specific issues (which I will describe in a
separate message), I found a few issues that could show up on other
systems:
1. configure errors out:
configure: error: you must have sys_mman.h on your system
This is because libopts/m4/libopts.m4 does this:
for f in sys_types sys_mman sys_param sys_stat sys_wait \
string errno stdlib memory setjmp
do eval as_ac_var=\${ac_cv_header_${f}_h}
test "X${as_ac_var}" = Xyes || {
]AC_MSG_ERROR([you must have ${f}.h on your system])[
}
done
I don't understand why configure insists on having sys/mman.h and
sys/wait.h, because the code has appropriate fallbacks for when
they are not present. My solution was to remove sys_mman and
sys_wait from the above list.
2. There's a bug in text_mmap.c (in the part that falls back to
reading a file if mmap is unavailable): the txt_zero_fd member of
tmap_info_t structure was not initialized to -1, so stayed at zero
and was closed (twice) by close_mmap_files, which caused an invalid
argument debug message from the runtime library.
My solution was this:
--- sharutils-4.13.4.orig/libopts/text_mmap.c 2013-03-31 19:56:09.000000000
+0300
+++ sharutils-4.13.4/libopts/text_mmap.c 2013-04-04 16:30:08.429263900
+0300
@@ -233,7 +233,7 @@ close_mmap_files(tmap_info_t * mi)
close(mi->txt_fd);
mi->txt_fd = AO_INVALID_FD;
-#if ! defined(MAP_ANONYMOUS)
+#if defined(HAVE_MMAP) && ! defined(MAP_ANONYMOUS)
if (mi->txt_zero_fd == AO_INVALID_FD)
return;
3. Using the -R option seems to bypass encoding and only records the
options to the RC file -- is that intended? If so, it seems to be
undocumented (I initially thought it was a bug, and only by
stepping through the code found out that uudecode -R simply exits
after outputting the options to the RC file).
4. When passed 2 or more base64-encoded files, uudecode barfs on the
second one:
d:\usr\eli\utils\sharutils-4.13.4>src\uudecode bar2.b64 bar3.b64
uudecode fatal error:
bar3.b64: Invalid or missing 'begin' line
This is because of the following snippet in decode:
if (strncmp (buf, "begin", 5) == 0)
{
char * scan = buf+5;
if (*scan == '-')
{
static char const base64[] = "ase64";
static char const encoded[] = "encoded";
check_begin_option:
if (*++scan == 'b')
{
if (strncmp (scan+1, base64, sizeof (base64) - 1) != 0)
goto bad_beginning;
if (do_base64)
goto bad_beginning; <<<<<<<<<<<<<<<<<<<<<<<
do_base64 = true;
scan += sizeof (base64); /* chars + 'b' */
do_base64 is a static variable that doesn't get reset after
processing each file.
My solution was to reset do_base64 after each file finishes
processing:
--- sharutils-4.13.4.orig/src/uudecode.c 2013-03-29 17:28:40.000000000
+0300
+++ sharutils-4.13.4/src/uudecode.c 2013-04-07 09:38:10.818181900 +0300
@@ -497,6 +518,7 @@ multiple input files.\n"));
error (0, errno, "%s", f);
exit_status |= UUDECODE_EXIT_NO_INPUT;
}
+ do_base64 = false;
}
}
5. Question: can /dev/stdout or - appear on the encoded file's begin
line? If it can, then processing several files when one of them
has such a line will not redirect output back to the original
stream, because this snippet:
if ( (strcmp (outname, "/dev/stdout") != 0)
&& (strcmp (outname, "-") != 0) )
{
rval = reopen_output (outname, mode);
if (rval != UUDECODE_EXIT_SUCCESS)
goto fail_return;
}
doesn't redirect stdout in that case. So it looks like uudecode
will continue writing to the previously decoded file, instead of
resetting stdout to the original stream/descriptor.
6. shar fails to record the time and the submitter of the archive:
# Made on by <>.
The time was missing because print_header_stamp assumed %Z format
in strftime always takes at most 4 characters:
static char const ftime_fmt[] = "%Y-%m-%d %H:%M %Z";
/*
* All fields are two characters, except %Y is four.
*/
char buffer[sizeof (ftime_fmt) + 4]; <<<<<<<<<<<<<<<
time_t now;
struct tm * local_time;
time (&now);
local_time = localtime (&now);
strftime (buffer, sizeof (buffer) - 1, ftime_fmt, local_time);
which is false on Windows; the code was not testing the return
value of strftime, so it didn't see the falure.
My solution was to reallocate the buffer if strftime returns zero:
--- sharutils-4.13.4.orig/src/shar.c 2013-03-23 00:23:48.000000000 +0200
+++ sharutils-4.13.4/src/shar.c 2013-04-07 13:41:14.742531000 +0300
@@ -916,13 +921,20 @@ print_header_stamp (FILE * fp)
static char const ftime_fmt[] = "%Y-%m-%d %H:%M %Z";
/*
* All fields are two characters, except %Y is four.
+ * The length of %Z is implementation-defined.
*/
- char buffer[sizeof (ftime_fmt) + 4];
+ size_t bsize = sizeof (ftime_fmt) + 4;
+ char *buffer = alloca (bsize);
time_t now;
struct tm * local_time;
+ size_t len;
time (&now);
local_time = localtime (&now);
- strftime (buffer, sizeof (buffer) - 1, ftime_fmt, local_time);
+ while ((len = strftime (buffer, bsize - 1, ftime_fmt, local_time)) == 0)
+ {
+ bsize += 40;
+ buffer = alloca (bsize);
+ }
fprintf (fp, made_on_comment_z, buffer, OPT_ARG(SUBMITTER));
}
The problem with submitter was because set_submitter assigned a
local buffer to the submitter option argument, without using
xstrdup:
static void
set_submitter (void)
{
char buffer[256]; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
char * uname = getuser (getuid ());
size_t len = strlen (uname);
if (uname == NULL)
fserr (SHAR_EXIT_FAILED, "getpwuid", "getuid()");
memcpy (buffer, uname, len);
buffer[len++] = '@';
gethostname (buffer + len, sizeof (buffer) - len);
SET_OPT_SUBMITTER(buffer); <<<<<<<<<<<<<<<<<<<<<<<<<
}
Solution: use xstrdup inside the SET_OPT_SUBMITTER call.
HTH
P.S. I'm not subscribed to this list, so please CC me on the
responses.
P.P.S. Thanks for maintaining sharutils!
- Building sharutils 4.13.4 with MinGW,
Eli Zaretskii <=