bug-gnu-utils
[Top][All Lists]
Advanced

[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!



reply via email to

[Prev in Thread] Current Thread [Next in Thread]