Package: mscompress
Version: 0.3-3.1
Severity: important
Tags: patch

Due to some assumptions about the signedness of char, mscompress and
msexpand fail to work at all on PowerPC (and probably other
architectures where char is unsigned by default, like ARM).

While fixing this, I noticed that it is also incredibly slow as it's
doing unbuffered IO.  The attached patch fixes this, as well.

-- System Information:
Debian Release: squeeze/sid
  APT prefers unstable
  APT policy: (500, 'unstable')
Architecture: i386 (i686)

Kernel: Linux 2.6.32-5-686 (SMP w/1 CPU core)
Locale: LANG=en_CA.UTF-8, LC_CTYPE=en_CA.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash

Versions of packages mscompress depends on:
ii  libc6                         2.11.2-6   Embedded GNU C Library: Shared lib

mscompress recommends no packages.

mscompress suggests no packages.

-- no debconf information
diff -u mscompress-0.3/ChangeLog mscompress-new/ChangeLog
--- mscompress-0.3/ChangeLog	2000-04-15 07:35:16.000000000 -0400
+++ mscompress-new/ChangeLog	2010-10-17 22:53:34.000000000 -0400
@@ -1,3 +1,9 @@
+2010-10-17  Julian Squires  <jul...@cipht.net>
+
+	* Fix platforms where char is unsigned, which caused arguments to
+	be ignored and output files to be truncated.
+	* Use buffered IO to massively improve performance.
+
 --0.3
   Autoconf
   Solaris getopt.h
diff -u mscompress-0.3/mscompress.c mscompress-new/mscompress.c
--- mscompress-0.3/mscompress.c	2000-04-15 09:15:38.000000000 -0400
+++ mscompress-new/mscompress.c	2010-10-17 23:00:24.000000000 -0400
@@ -140,18 +140,18 @@
 }
 
 int
-getbyte (int f)
+getbyte (FILE *f)
 {
   unsigned char b;
 
   /* Is there a better way?  */
-  if (read (f, &b, sizeof (b)) != 1)
+  if (fread (&b, sizeof (b), 1, f) != 1)
     return -1;
   return b;
 }
 
 int
-compress (int in, char *inname, int out, char *outname)
+compress (FILE *in, char *inname, FILE *out, char *outname)
 {
   int ch, i, run, len, match, size, mask;
   char buf[17];
@@ -170,7 +170,7 @@
     }
 
 
-  if (fstat (in, &st) < 0)
+  if (fstat (fileno(in), &st) < 0)
     {
       perror (inname);
       return -1;
@@ -190,27 +190,27 @@
 #endif
 
   /* Write header to the output file */
-  if (write (out, &magic1, sizeof (magic1)) != sizeof (magic1))
+  if (fwrite (&magic1, sizeof (magic1), 1, out) != 1)
     {
       perror (outname);
       free (buffer);
       return -1;
     }
-  if (write (out, &magic2, sizeof (magic2)) != sizeof (magic2))
+  if (fwrite (&magic2, sizeof (magic2), 1, out) != 1)
     {
       perror (outname);
       free (buffer);
       return -1;
     }
 
-  if (write (out, &magic3, sizeof (magic3)) != sizeof (magic3))
+  if (fwrite (&magic3, sizeof (magic3), 1, out) != 1)
     {
       perror (outname);
       free (buffer);
       return -1;
     }
 
-  if (write (out, &filesize, sizeof (filesize)) != sizeof (filesize))
+  if (fwrite (&filesize, sizeof (filesize), 1, out) != 1)
     {
       perror (outname);
       free (buffer);
@@ -268,7 +268,7 @@
 	    }
 	  if (!((mask += mask) & 0xFF))
 	    {
-	      if (write (out, buf, size) != size)
+	      if (fwrite (buf, sizeof(unsigned char), size, out) != size)
 		{
 		  perror (outname);
 		  free (buffer);
@@ -283,7 +283,7 @@
   while (len > 0);
 
   if (size > 1)
-    if (write (out, buf, size) != size)
+    if (fwrite (buf, sizeof(unsigned char), size, out) != size)
       {
 	perror (outname);
 	free (buffer);
@@ -309,9 +309,9 @@
 void
 main (int argc, char **argv)
 {
-  int in, out;
+  FILE *in, *out;
   char *argv0;
-  char c;
+  int c;
   char name[0x100];
 
   argv0 = argv[0];
@@ -350,8 +350,8 @@
 	  continue;
 	}
 
-      in = open (argv[0], O_RDONLY);
-      if (in < 0)
+      in = fopen (argv[0], "rb");
+      if (in == NULL)
 	{
 	  perror (argv[0]);
 	  exit (1);
@@ -360,16 +360,16 @@
       strcpy (name, argv[0]);
       strcat (name, "_");
 
-      out = open (name, O_WRONLY | O_CREAT | O_EXCL, 0644);
-      if (out < 0)
+      out = fopen (name, "wxb");
+      if (out == NULL)
 	{
 	  perror (name);
 	  exit (1);
 	}
 
       compress (in, argv[0], out, name);
-      close (in);
-      close (out);
+      fclose (in);
+      fclose (out);
 
       argc--;
       argv++;
diff -u mscompress-0.3/msexpand.c mscompress-new/msexpand.c
--- mscompress-0.3/msexpand.c	2000-04-15 09:15:45.000000000 -0400
+++ mscompress-new/msexpand.c	2010-10-17 22:47:31.000000000 -0400
@@ -36,18 +36,18 @@
 #define F 16
 
 int
-getbyte (int f)
+getbyte (FILE *f)
 {
   unsigned char b;
 
   /* Is there a better way?  */
-  if (read (f, &b, sizeof (b)) != 1)
+  if (fread (&b, sizeof (b), 1, f) != 1)
     return -1;
   return b;
 }
 
 int
-expand (int in, char *inname, int out, char *outname)
+expand (FILE *in, char *inname, FILE *out, char *outname)
 {
   int bits, ch, i, j, len, mask;
   unsigned char *buffer;
@@ -58,7 +58,7 @@
   unsigned short reserved;
   unsigned int filesize;
 
-  if (read (in, &magic1, sizeof (magic1)) != sizeof (magic1))
+  if (fread (&magic1, sizeof (magic1), 1, in) != 1)
     {
       perror (inname);
       return -1;
@@ -70,19 +70,19 @@
   if (magic1 == 0x44445A53L)
 #endif
     {
-      if (read (in, &magic2, sizeof (magic2)) != sizeof (magic2))
+      if (fread (&magic2, sizeof (magic2), 1, in) != 1)
 	{
 	  perror (inname);
 	  return -1;
 	}
 
-      if (read (in, &reserved, sizeof (reserved)) != sizeof (reserved))
+      if (fread (&reserved, sizeof (reserved), 1, in) != 1)
 	{
 	  perror (inname);
 	  return -1;
 	}
 
-      if (read (in, &filesize, sizeof (filesize)) != sizeof (filesize))
+      if (fread (&filesize, sizeof (filesize), 1, in) != 1)
 	{
 	  perror (inname);
 	  return -1;
@@ -104,19 +104,19 @@
   if (magic1 == 0x4A41574BL)
 #endif
     {
-      if (read (in, &magic2, sizeof (magic2)) != sizeof (magic2))
+      if (fread (&magic2, sizeof (magic2), 1, in) != 1)
 	{
 	  perror (inname);
 	  return -1;
 	}
 
-      if (read (in, &magic3, sizeof (magic3)) != sizeof (magic3))
+      if (fread (&magic3, sizeof (magic3), 1, in) != 1)
 	{
 	  perror (inname);
 	  return -1;
 	}
 
-      if (read (in, &reserved, sizeof (reserved)) != sizeof (reserved))
+      if (fread (&reserved, sizeof (reserved), 1, in) != 1)
 	{
 	  perror (inname);
 	  return -1;
@@ -136,15 +136,14 @@
     }
   else
     {
-      fprintf (stderr, "%s: This is not a MS-compressed file\n", inname);
+      fprintf (stderr, "%s: This is not an MS-compressed file\n", inname);
       return -1;
     }
 
-
   buffer = malloc (N);
   if (!buffer)
     {
-      fprintf (stderr, "%s:No memory\n", inname);
+      fprintf (stderr, "%s: No memory\n", inname);
       return -1;
     }
 
@@ -170,7 +169,7 @@
 	      while (len--)
 		{
 		  buffer[i] = buffer[j];
-		  if (write (out, &buffer[i], 1) != 1)
+		  if (fwrite (&buffer[i], sizeof (unsigned char), 1, out) != 1)
 		    {
 		      perror (outname);
 		      return -1;
@@ -187,7 +186,7 @@
 	      if (ch == -1)
 		break;
 	      buffer[i] = ch;
-	      if (write (out, &buffer[i], 1) != 1)
+	      if (fwrite (&buffer[i], sizeof (unsigned char), 1, out) != 1)
 		{
 		  perror (outname);
 		  return -1;
@@ -218,9 +217,9 @@
 void
 main (int argc, char **argv)
 {
-  int in, out;
+  FILE *in, *out;
   char *argv0;
-  char c;
+  int c;
   char name[0x100];
 
   argv0 = argv[0];
@@ -247,7 +246,7 @@
     {
       if (isatty (STDIN_FILENO))
 	usage (argv0);
-      if (expand (STDIN_FILENO, "STDIN", STDOUT_FILENO, "STDOUT") < 0)
+      if (expand (stdin, "STDIN", stdout, "STDOUT") < 0)
 	exit (1);
       exit (0);
     }
@@ -262,8 +261,8 @@
 	  continue;
 	}
 
-      in = open (argv[0], O_RDONLY);
-      if (in < 0)
+      in = fopen (argv[0], "rb");
+      if (in == NULL)
 	{
 	  perror (argv[0]);
 	  exit (1);
@@ -272,16 +271,16 @@
       strcpy (name, argv[0]);
       name[strlen (name) - 1] = 0;
 
-      out = open (name, O_WRONLY | O_CREAT | O_EXCL, 0644);
-      if (out < 0)
+      out = fopen (name, "wxb");
+      if (out == NULL)
 	{
 	  perror (name);
 	  exit (1);
 	}
 
       expand (in, argv[0], out, name);
-      close (in);
-      close (out);
+      fclose (in);
+      fclose (out);
 
       argc--;
       argv++;

Reply via email to