delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1999/11/10/18:50:41

From: "Juan Manuel Guerrero" <ST001906 AT HRZ1 DOT HRZ DOT TU-Darmstadt DOT De>
Organization: Darmstadt University of Technology
To: djgpp AT delorie DOT com
Date: Wed, 10 Nov 1999 23:20:31 +0100
Subject: Re: djlsr203 (990819)
X-mailer: Pegasus Mail for Windows (v2.54DE)
Message-ID: <64E74171C6@HRZ1.hrz.tu-darmstadt.de>
Reply-To: djgpp AT delorie DOT com

On  Tue, 26 Oct 1999, Eli Zaretskii wrote:

>On Tue, 12 Oct 1999, Juan Manuel Guerrero, Student, FB05 wrote:
>
>> When decompressing a tgz-file with an entry of the form:
>> libg++-1.2.3/libg++/readme.g++
>> the program performs the substitution:
>> ++  -->  plus.
>> It should be clear that this substitution must be applied to all
>> occuriences of "++" and not only to the first as the program does.
>
>Thanks for the report and the patches.
>
>I corrected the problem in DJTAR a bit differently; see the patch below.
>The corrected version will be in DJGPP v2.03.

First: sorry for delay but i was busy.

I have applied your patch and i think it is worth to note that there is still
an error in function: get_new_name.
I will make reference to the original code from djlsr203 (990819).
If you inspect the code concerning the tests and substitutions 
you will see that it looks like this:

       if (info)
       {
         code for substitution: .info-NNN -> .iNNN
       }
       else
       {
         code for testing all the other things and
         executing the corresponding substitutions.
       }

This is an error.
Example:
  libg++-1.2.3/libg++.info-123
The string ".info-" will be found but the string "++" will never be found.
At least in this case the tests make no sense.
Even worse, if you inspect the code following the else statement you will see
that the same way of testing is applied:

       if (tgz)
       {
         code for substitution: .tar.gz -> .tgz
       }
       else
       {
         code for testing "++" occuriences and
         executing the corresponding substitutions, etc.
       }

This will fail again at least with this example:
  libg++-1.2.3/foo.tar.gz
The occurience of "tar.gz" will be detected but NOT the occurience of "++".
The error is makeing the execution of the next test depending
on the result of the last test. In my opinion ALL or ALMOST ALL tests
MUST be applied in a sequential way. What i mean is:
       if (info)
       {
         code for substitution: .info-NNN -> .iNNN
       }
       if (tgz)
       {
         code for substitution: .tar.gz -> .tgz
       }
       if (plus)
       {
         code for substitution: ++ -> xx
       }
       etc, etc, etc.

For my private use of DJTAR I have defined
the following tests and tests sequences.
(Private use means that my code works, but the quality of it is poor
and was never intented for submission.)

1)     MULTIPLE DOT test.
       This code tests for occuriences of multiple dots
       in the directory part of the path.
       Example:
               ./../foo-1.2.3/bar-4.5/ -> ./../foo-1.2-3/bar-4.5/
               .\..\foo-1.2.3\bar-4.5\ -> .\..\foo-1.2-3\bar-4.5\
       1. File names will NOT been modified by this test and are treated later.
       2. If there are mixed slashs and backslashs the code will fail.

2)     NOT ALLOWED CHARS test.
       This code will delete from the whole tar entry (dir part and file name part)
       all spaces and tabs.
       It will also replace chars that are not allowed on MSDOS, especially
       + -> x
       = -> #
       It tests for ALL not allowed chars under MSDOS and performs an arbitrary substitution
       (see patch). Special testing for "++" is now superfluous.


3)     TAR.ANY_COMPRESSOR_EXTENSION test.
       Any compressor extension means: .z, .Z, .gz, .bz, .bz2, .bzip2, .Y
       This implies the following substitutions:
          foo.tar.(z,Z)           -->  foo.taz
          foo.tar.gz              -->  foo.tgz
          foo.tar.(bz,bz2,bzip2)  -->  foo.tbz
          foo.tar.Y               -->  foo.tay
       Because the extension is important, one more substitution
       is performed:
          foo-1.2.3.4.(taz,tgz,tbz,tay) --> foo-1234.(taz,tgz,tbz,tay)
       If this substitution is not applied, the original DJTAR multiple dot test
       will perform the following substitution:
          foo-1.2.3.4.tar.gz  -->  foo-1.2-3-4-tgz  -->  foo-1.2-3
       The last substitution (truncation) is done by DOS and
       the average user will never notice that the file is an archive.

4)     INFO test.
4.1)   Test for compressed info files.
       Texinfo-3.12 supports the following decompressors:
       uncompress, gunzip, bunzip2 and unyabba.
       For the DJGPP port of Texinfo-3.12 the following applies:
          foo     -->  foo.gz
          foo.inf -->  foo.igz or foo.inz
          foo.iN  -->  foo.iNz
          foo.iNN -->  foo.NNz
          foo.NNN -->  foo-NNN.z
       This implies the following substitutions:
          foo.info.(z,Z,gz,bz,bz2,bzip2,Y)     -->  foo.in(z,b,y)
          foo.info-N.(z,Z,gz,bz,bz2,bzip2,Y)   -->  foo.iN(z,b,y)
          foo.info-NN.(z,Z,gz,bz,bz2,bzip2,Y)  -->  foo.NN(z,b,y)
          foo.info-NNN.(z,Z,gz,bz,bz2,bzip2,Y) -->  foo-NNN.(z,bz2,y)
       (z,Z,gz,bz,bz2,bzip2,Y) means: one of the possible compressor extensions.
       N means: one info digit.
       I know that there is no MSDOS/DJGPP port for some of the compressors
       but the files must be extracted correctely from the tar-archive.
4.2)   Test for NOT compressed info files.
       For the DJGPP port of Texinfo-3.12 the following substitutions applies:
          foo.info      -->  foo.inf
          foo.info-N    -->  foo.inN
          foo.info-NN   -->  foo.iNN
          foo.info-NNN  -->  foo.NNN
          foo.info-NNNN -->  foo-NNNN

5)     SPECIAL FILES test.
       The definition of a special file is COMPLETELY ARBITRARY
       and represents only my opinion.
       Renaming of special files:
          .foo            -->  _foo
          .lex.           -->  _lex.
          .tab.           -->  _tab.
          config.h.in     -->  config_h.in
          config.h.bot    -->  config_h.bot
          config.h.top    -->  config_h.top
          Makefile.am.in  -->  Mkfileam.in
          Makefile.in.in  -->  Mkfilein.in
          intlh.inst.in   -->  intlhinst.in
          po2tbl.sed.in   -->  po2tblsed.in
          texinfo.texi    -->  texinfo.txi
          ChangeLog-      -->  CLog
          ChangeLog.      -->  CLog
       All other files that can not be extracted without violating
       the 8.3 file name restriction (means: multiple dots, ignoring
       difference between upper and lower case names, etc, etc, etc)
       will fail to be extracted. This is COMPLETELY INTENSIONAL.
       The user shall notice that something is wrong.
       The original DJTAR will extract this file as:
          foo.1999Nov11.patch.gz  --> foo.1999Nov11-patch-gz  --> foo.199
       The last truncation is done by DOS and in my opinion an average user
       will never notice that this is a gziped patch file for foo.
       I don't like this SILENT conversions of files. I prefer a warning and
       then skipping the file so I get a tarchange.lst file which I can use
       to make my own change list file. But this is only my private opinion.

To make all this points clear:
1. The things concerning the if-else command sequence is in my opinion a bug
   and should be corrected.
2. The tests and tests sequence i have defined reflects only my private opinion
   and can be descarted by the maintainers of DJTAR.

Although my code is probably of poor quality i send you a patch
anyway. May be you can extract something usefull.
The patch is based on the original DJLSR203 code.

Regards,
Guerrero, Juan Manuel.

diff -aprNC3 djtar.alt/djtar.c djtar.neu/djtar.c
*** djtar.alt/djtar.c	Thu Jun  3 13:27:42 1999
--- djtar.neu/djtar.c	Wed Nov 10 12:50:14 1999
***************
*** 2,7 ****
--- 2,8 ----
  /* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+ #include <ctype.h>
  #include <stdlib.h>
  #include <unistd.h>
  #include <limits.h>
*************** guess_file_type(char *buf, register size
*** 274,398 ****
  }
  
  /*------------------------------------------------------------------------*/
! char new[2048];  /* got to think about LFN's! */
  
! char *
! get_new_name(char *name_to_change, int *should_be_written)
  {
!   char *changed_name, *info;
  
!   /* ONLY_DIR says to extract only files which are siblings
!      of that directory.  */
!   *should_be_written = list_only == 0;
!   if (*should_be_written &&
!       only_dir && strncmp(only_dir, name_to_change, strlen(only_dir)))
!     *should_be_written = 0;
  
!   changed_name = get_entry(name_to_change);
!   if (*should_be_written && !to_stdout && NO_LFN(changed_name))
    {
!     info = strstr(changed_name, ".info-");
!     if (info)
      {
!       strcpy(new, changed_name);
!       info = strstr(new, ".info-");
!       strcpy(info+2, info+6);
!       fprintf(log_out, "[ changing %s to %s ]\n", changed_name, new);
      }
      else
      {
!       char *tgz = strstr(changed_name, ".tar.gz");
!       if (tgz)
        {
! 	strcpy(new, changed_name);
! 	tgz = strstr(new, ".tar.gz");
! 	strcpy(tgz, ".tgz");
! 	strcat(tgz, tgz+7);
! 	fprintf(log_out, "[ changing %s to %s ]\n", changed_name, new);
        }
!       else
        {
! 	char *plus = strstr(changed_name, "++"), *plus2;
! 	if (plus)
! 	{
! 	  strcpy(new, changed_name);
! 	  plus2 = strstr(new, "++");
! 	  strcpy(plus2, "plus");
! 	  strcpy(plus2+4, plus+2);
! 	  fprintf(log_out, "[ changing %s to %s ]\n", changed_name, new);
! 	}
! 	else
! 	{
! 	  strcpy(new, changed_name);
! 	}
        }
      }
!     changed_name = new;
  
!     if (dot_switch)
      {
!       char *p = changed_name, *name_start = changed_name;
!       int state = 0;
!       /* 0 = start of item
! 	 1 = before dot (not counting initial dot), but not first char
! 	 2 = after first dot */
! 
!       /* ".gdbinit" -> "_gdbinit"
! 	 "emacs-19.28.90/ChangeLog" -> "emacs-19.28-90/ChangeLog"
! 	 "./dir/file" -> "./dir/file"
! 	 "sh.lex.c" -> "sh_lex.c"
!       */
!       while (*p)
        {
! 	switch (*p++)
! 	{
! 	  case '/':
! 	  case '\\':
! 	    state = 0;
! 	    name_start = p;
! 	    break;
! 	  case '.':
! 	    /* Don't waste our limited 8-char real estate in the
! 	       name part too early, unless the name is really short. */
! 	    if (state == 1 && p - name_start < 5)
! 	    {
! 	      size_t namelen    = strlen(p);
! 	      char *next_slash  = memchr(p, '/', namelen);
! 	      char *next_bslash = memchr(p, '\\', namelen);
! 	      char *next_dot    = memchr(p, '.', namelen);
! 
! 	      /* Find where this name ends.  */
! 	      if (next_slash == (char *)0)
! 	      {
! 		if (next_bslash)
! 		  next_slash = next_bslash;
! 		else
! 		  next_slash = p + namelen;
! 	      }
! 
! 	      else if (next_bslash && next_bslash < next_slash)
! 		next_slash = next_bslash;
! 
! 	      /* If name has more dots, convert this one to `_'. */
! 	      if (next_dot && next_dot < next_slash)
! 	      {
! 		p[-1] = '_';
! 		break;      /* don't bump `state' */
! 	      }
! 	    }
! 
! 	    /* Leave "./", "../", "/." etc. alone.  */
! 	    if (state != 0 ||
! 		(*p && *p != '/' && *p != '\\' && *p != '.'))
! 	      p[-1] = "_.-"[state];
! 	    if (state < 2) state++;
! 	    break;
! 	  default:
! 	    if (state == 0) state = 1;
! 	}
        }
      }
    }
    return changed_name;
  }
  
--- 275,728 ----
  }
  
  /*------------------------------------------------------------------------*/
! void
! replace_multiple_dots_in_path(char *changed_name)
! {
!   char dir_separator = '/';
  
!   if (strchr(changed_name, '\\'))
!     dir_separator = '\\';
! 
!   if (dir_separator)
!   {
!     char *dir, *dot, *slash, temp;
! 
!     dir = changed_name;
!     while ((slash = strchr(dir, dir_separator)))
!     {
!       temp = *++slash; /* remember char after slash. */
!       *slash = '\0';
!       dot = strchr(dir, '.');
!       if (dot && *(dot + 1) != '.')
!         while ((dot = strchr(++dot, '.'))) /* Don't modify: "./", "../", "/.". */
!           *dot = '-';
!       *slash = temp; /* restore char. */
!       dir = slash;   /* next directory. */
!     }
!   }
! }
! 
! /*------------------------------------------------------------------------*/
! /******************************************************************
!  *  Substitutions for not allowed characters in archive entries.  *
!  *  1.: Delete white space and tabs.                              *
!  *  2.: Subtitute chars that are not allowed under MSDOS.         *
!  ******************************************************************/
! 
! void
! replace_illegal_chars(char *changed_name)
  {
!   static struct {
!          const char orig_char, new_char;
!   } illegal_chars[] = {
!          { '+',   'x'  },
!          { '=',   '#'  },
!          { ',',   '`'  },
!          { ';',   '\'' },
!          { ':',   '@'  },
!          { '\"',  '^'  },
!          { '[',   '{'  },
!          { ']',   '}'  },
!          { '<',   '('  },
!          { '>',   ')'  },
!          { '|',   '!'  },
!          { '\\',  '$'  },
!          { '?',   '%'  },
!          { '*',   '&'  }
!   };
!   static int index_max = sizeof illegal_chars / sizeof illegal_chars[0];
!   int index;
!   char *illegal_char;
! 
!   illegal_char = changed_name;
!   while ((illegal_char = strchr(illegal_char, ' ')))
!     strcpy(illegal_char, illegal_char + 1);  /* delete space and tab. */
  
!   for (index = 0; index < index_max; index++)
!   {
!     illegal_char = changed_name;
!     while ((illegal_char = strchr(illegal_char, illegal_chars[index].orig_char)))
!       *illegal_char = illegal_chars[index].new_char;
!   }
! }
  
! /*------------------------------------------------------------------------*/
! /****************************************************
!  *  Substitutions for known archive extensions.     *
!  *    filename.tar.z        -->  filename.taz       *
!  *    filename.tar.Z        -->  filename.taz       *
!  *    filename.tar.gz       -->  filename.tgz       *
!  *    filename.tar.bzip2    -->  filename.tbz       *
!  *    filename.tar.bz2      -->  filename.tbz       *
!  *    filename.tar.bz       -->  filename.tbz       *
!  *    filename.tar.Y        -->  filename.tay       *
!  *                                                  *
!  *  An archive extension must always be preserved.  *
!  *    filename-1.2.3.4.taz  -->  filename-1234.taz  *
!  *    filename-1.2.3.4.tgz  -->  filename-1234.tgz  *
!  *    filename-1.2.3.4.tbz  -->  filename-1234.tbz  *
!  *    filename-1.2.3.4.tay  -->  filename-1234.tay  *
!  ****************************************************/
! 
! void
! replace_archive_extensions(char *changed_name)
! {
!   static struct {
!          const char *orig_ext, *new_ext;
!          const int   orig_ext_len;
!   } tar_zext[] = {
!          { ".tar.z",     ".taz",  6 },
!          { ".tar.Z",     ".taz",  6 },
!          { ".tar.gz",    ".tgz",  7 },
!          { ".tar.bzip2", ".tbz", 11 },
!          { ".tar.bz2",   ".tbz",  9 },
!          { ".tar.bz",    ".tbz",  7 },
!          { ".tar.Y",     ".tay",  6 }
!   };
!   static int index_max = sizeof tar_zext / sizeof tar_zext[0];
!   int index;
!   char *filename = basename(changed_name);
! 
!   for (index = 0; index < index_max; index++)
    {
!     char *tar_any_zext = strstr(filename, tar_zext[index].orig_ext);
!     if (tar_any_zext)
      {
! 
!       char *dot;
!       tar_any_zext = strstr(filename, tar_zext[index].orig_ext);
!       strcpy(tar_any_zext, tar_zext[index].new_ext);
!       strcat(tar_any_zext, tar_any_zext + tar_zext[index].orig_ext_len);
! 
!       dot = strchr(filename, '.');
!       while ((dot = strchr(dot, '.')) != tar_any_zext--)
!         strcpy(dot, dot + 1);
      }
+   }
+ }
+ 
+ /*------------------------------------------------------------------------*/
+ /**********************************************************************
+  *  Substitutions for info files.                                     *
+  *  1.: uncompressed info file:                                       *
+  *      foo.info        --> foo.inf                                   *
+  *      foo.info-N      --> foo.inN                                   *
+  *      foo.info-NN     --> foo.iNN                                   *
+  *      foo.info-NNN    --> foo.NNN                                   *
+  *      foo.info-NNNNN  --> fo-NNNNN                                  *
+  *  2.: compressed info file:                                         *
+  *      foo.info.(z,Z,gz,bz,bz2,bzip2,Y)        --> foo.in(z,b,y)     *
+  *      foo.info-N.(z,Z,gz,bz,bz2,bzip2,Y)      --> foo.iN(z,b,y)     *
+  *      foo.info-NN.(z,Z,gz,bz,bz2,bzip2,Y)     --> foo.NN(z,b,y)     *
+  *      foo.info-NNN.(z,Z,gz,bz,bz2,bzip2,Y)    --> foo-NNN.(z,b,y)   *
+  *      foo.info-NNNNN.(z,Z,gz,bz,bz2,bzip2,Y)  --> fo-NNNNN.(z,b,y)  *
+  *  with:                                                             *
+  *        z,Z,gz,bz,bz2,bzip2,Y: known compressor extensions.         *
+  **********************************************************************/
+ 
+ #define OFFSET       6    /* OFFSET is the length of string ".info-". */
+ #define EIGHT_CHARS  8    /* max characters of valid dos file name. */
+ #define SEVEN_CHARS  7
+ 
+ int
+ replace_info_extension(char *changed_name)
+ {
+ 
+   static struct {
+          const char *orig_ext;
+          const int   orig_ext_len;
+   } any_z_ext[] = {
+          { ".z",     2 },
+          { ".Z",     2 },
+          { ".gz",    3 },
+          { ".bzip2", 6 },
+          { ".bz2",   4 },
+          { ".bz",    3 },
+          { ".Y",     2 }
+   };
+ 
+   static int index_max = sizeof any_z_ext / sizeof any_z_ext[0];
+   char *filename = basename(changed_name);
+   char *info_ext = strstr(filename, ".info-");
+ 
+   /* longfoo.info-bar  -->  long-inf.bar */
+   if (info_ext && isalpha(*(info_ext + OFFSET)))
+   {
+     if (info_ext - filename > 4)
+       strcpy(filename + 4, info_ext);
+     info_ext = strstr(filename, ".info-");
+     *info_ext = '_';                 /* .  -->  _ */
+     *(info_ext + OFFSET - 1) = '.';  /* -  -->  . */
+     return 0;
+   }
+ 
+   /* info extension with an numerical index. */
+   if (info_ext)
+   {
+     int info_digits;
+     char *dot = strchr(info_ext + OFFSET, '.'); /* first dot beyond ".info-" */
+     if (dot) /* number of digits in .info-NNNNNNN */
+       info_digits = (int) (dot - (info_ext + OFFSET));
      else
+       info_digits = strlen(info_ext + OFFSET);
+ 
+     if (info_digits > 6)
+       /* info digits to large for file name space (8 chars).
+          At least place for 2 chars in file name must remain.
+          File name must looks like: x-NNNNNN or x-NNNNNN.(z,Z,gz,bz,bz2,bzip2,Y)
+          z,Z,gz,bz,bz2,bzip2,Y: possible compressor extensions.
+       */
+       return 1; /* let the user decide. */
+     else if (info_digits > 3)
      {
!       char *any_zext;
!       int filename_len = (int) (info_ext - filename);
!       if (SEVEN_CHARS - (filename_len + info_digits) >= 0)
!         /* File name plus info digits fits in 8 chars.
!            Info digits will be appended to file name.
!            foo.info-NNNN    -->  foo-NNNN  or
!            foo.info-NNNN.(z,Z,gz,bz,bz2,bzip2,Y)  -->  foo-NNNN.(z,Z,gz,bz,bz2,bzip2,Y)
!         */
!         strcpy (filename + filename_len, info_ext + OFFSET - 1);
!       else
        {
!         /* File name has 8 or more chars or
!            file name plus info digits are more than 8 chars long.
!            File name will be truncated accordingly.
!            longfilename.info-NNNN  -->  lon-NNNN  or
!            longfilename.info-NNNN.(z,Z,gz,bz,bz2,bzip2,Y) --> lon-NNNN.(z,Z,gz,bz,bz2,bzip2,Y)
!            foo.info-NNNNN  -->  fo-NNNNN  or
!            foo.info-NNNNN.(z,Z,gz,bz,bz2,bzip2,Y)  -->  fo-NNNNN.(z,Z,gz,bz,bz2,bzip2,Y)
!         */
!         strcpy (filename + SEVEN_CHARS - info_digits, info_ext + OFFSET - 1);
        }
!       if ((any_zext = strstr(filename, ".bzip2")))
!         strcpy(any_zext + 3, any_zext + 5); /* .bzip2  -->  .bz2. */
!     }
!     else if (info_digits == 3)
!     {
!       if (dot) /* info file has probably an compressor extension. */
!       {
!         char *any_zext;
!         int filename_len = (int) (info_ext - filename);
!         if (SEVEN_CHARS - (filename_len + info_digits) >= 0)
!           /* File name plus info digits fits in 8 chars.
!              Info digits will be appended to file name.
!              foo.info-NNN.(z,Z,gz,bz,bz2,bzip2,Y)  -->  foo-NNN.(z,Z,gz,bz,bz2,bzip2,Y)
!           */
!           strcpy (filename + filename_len, info_ext + OFFSET - 1);
!         else
!         {
!           /* File name has 8 or more chars or
!              file name plus info digits are more than 8 chars long.
!              File name will be truncated accordingly.
!              longfilename.info-NNN.(z,Z,gz,bz,bz2,bzip2,Y) --> long-NNN.(z,Z,gz,bz,bz2,bzip2,Y)
!              foobar.info-NNN.(z,Z,gz,bz,bz2,bzip2,Y)  -->  foob-NNN.(z,Z,gz,bz,bz2,bzip2,Y)
!           */
!           strcpy (filename + SEVEN_CHARS - info_digits, info_ext + OFFSET - 1);
!         }
!         if ((any_zext = strstr(filename, ".bzip2")))
!           strcpy(any_zext + 3, any_zext + 5); /* .bzip2  -->  .bz2. */
!       }
!       else /* uncompressed info file. */
!         /* filename.info-NNN  -->  filename.NNN */
!         strcpy(info_ext + 1, info_ext + OFFSET);
!     }
!     else if (info_digits <= 2)
!     {
!       int index;
! 
!       switch (info_digits) /* Delete ".info-" string. */
!       {
!       case 2:  /* foo.info-NN.(z,Z,gz,bz,bz2,bzip2,Y)  -->  foo.iNN.(z,Z,gz,bz,bz2,bzip2,Y) */
!         strcpy(info_ext + 2, info_ext + OFFSET);
!         break;
!       case 1:  /* foo.info-N.(z,Z,gz,bz,bz2,bzip2,Y)   -->  foo.inN.(z,Z,gz,bz,bz2,bzip2,Y) */
!         strcpy(info_ext + 3, info_ext + OFFSET);
!         break;
!       }      
! 
!       for (index = 0; index < index_max; index++)
        {
!         char *any_zext = strstr(info_ext, any_z_ext[index].orig_ext);
!         if (any_zext) /* info file has an compressor extension. */
!         {
!           /* Info digits fits in extension. */
!           switch (*(any_zext + 1))
!           {
!           case 'z':  case 'Z':
!             /********************************
!              * foo.iNN.(z,Z)  -->  foo.iNNz *
!              * foo.inN.(z,Z)  -->  foo.inNz *
!              ********************************/
!             strcpy(any_zext, any_zext + 1);
!             break;
!           case 'g':
!             /*****************************
!              * foo.iNN.gz  -->  foo.iNNz *
!              * foo.inN.gz  -->  foo.inNz *
!              *****************************/
!             strcpy(any_zext, any_zext + 2);
!             break;
!           case 'b':
!             /*****************************************
!              * foo.iNN.(bz,bz2,bzip2)  -->  foo.iNNb *
!              * foo.inN.(bz,bz2,bzip2)  -->  foo.inNb *
!              *****************************************/
!             strcpy(any_zext, any_zext + 1);
!             strcpy(any_zext + 1, any_zext + any_z_ext[index].orig_ext_len - 1);
!             break;
!           case 'Y':
!             /****************************
!              * foo.iNN.Y  -->  foo.iNNy *
!              * foo.inN.Y  -->  foo.inNy *
!              ****************************/
!             strcpy(any_zext, any_zext + 1);
!             break;
!           }
! 
!           switch (info_digits)
!           {
!           case 2:  /* foo.iNN(z,b,y)   -->  foo.NN(z,b,y) */
!             strcpy(info_ext + 1, info_ext + 2);
!             break;
!           case 1:  /* foo.inN(z,b,y)   -->  foo.iN(z,b,y) */
!             strcpy(info_ext + 2, info_ext + 3);
!             break;
!           }
!           break;
!         }
        }
      }
!   }
  
!   info_ext = strstr(filename, ".info.");
!   if (info_ext)
!   {
!     int index;
!     for (index = 0; index < index_max; index++)
      {
!       char *any_zext = strstr(info_ext, any_z_ext[index].orig_ext);
!       if (any_zext)
        {
!         /* filename.info.(z,Z,gz,bz,bz2,Y) -> filename.in(z,b,y) */
!         switch (*(any_zext + 1))
!         {
!         case 'z':  case 'Z':  /* foo.info.(z,Z)  -->  foo.inz */
!           strcpy(info_ext + 3, any_zext + 1);
!           break;
!         case 'g':  /* foo.info.gz  -->  foo.inz */
!           strcpy(info_ext + 3, any_zext + 2);
!           break;
!         case 'b':  /* foo.info.(bz,bz2,bzip2)  -->  foo.inb */
!           strcpy(info_ext + 3, any_zext + 1);
!           strcpy(info_ext + 4, any_zext + any_z_ext[index].orig_ext_len - 3);
!           break;
!         case 'Y':  /* foo.info.Y  -->  foo.iny */
!           strcpy(any_zext, any_zext + 1);
!           break;
!         }
        }
      }
    }
+   return 0;
+ }
+ 
+ /*------------------------------------------------------------------------*/
+ 
+ void
+ rename_special_files(char *changed_name)
+ {
+   static struct {
+          const char *orig_name, *new_name;
+          const int   orig_name_len;
+ 
+   } file_names[] = {
+          { "Makefile.am.in", "Mkfileam.in",  14 },
+          { "Makefile.in.in", "Mkfilein.in",  14 },
+          { "intlh.inst.in",  "intlhinst.in", 13 },
+          { "po2tbl.sed.in",  "po2tblsed.in", 13 },
+          { "texinfo.texi",   "texinfo.txi",  12 },
+          { "ChangeLog-",     "CLog",         10 },
+          { "ChangeLog.",     "CLog",         10 }
+   };
+   static int index_max = sizeof file_names / sizeof file_names[0];
+   int index;
+   char *dot, *rest_of_line, *filename =  basename(changed_name);
+ 
+   /*************************************
+    *  .foo          -->  _foo          *
+    *  .lex.         -->  _lex.         *
+    *  .tab.         -->  _tab.         *
+    *  config.h.in   -->  config_h.in   *
+    *  config.h.bot  -->  config_h.bot  *
+    *  config.h.top  -->  config_h.top  *
+    *************************************/
+ 
+   if (*filename == '.')
+     *filename ='_';
+   if ((dot = strstr(filename, ".lex.")))
+     *dot = '_';
+   if ((dot = strstr(filename, ".tab.")))
+     *dot = '_';
+   if (strstr(filename, "config.h."))
+   {
+     if ((dot = strstr(filename, ".h.in")))
+       *dot = '_';
+     if ((dot = strstr(filename, ".h.bot")))
+       *dot = '_';
+     if ((dot = strstr(filename, ".h.top")))
+       *dot = '_';
+   }
+ 
+   for (index = 0; index < index_max; index++)
+   {
+     rest_of_line = strstr(filename, file_names[index].orig_name) +
+                    file_names[index].orig_name_len;
+     if (rest_of_line != (char *) file_names[index].orig_name_len)
+     {
+       strcpy(filename, file_names[index].new_name);
+       strcat(filename, rest_of_line);
+       break;
+     }
+   }
+ }
+ 
+ /*------------------------------------------------------------------------*/
+ char new [2048];  /* got to think about LFN's! */
+ 
+ char *
+ get_new_name(char *name_to_change, int *should_be_written)
+ {
+   char *changed_name;
+ 
+   /* ONLY_DIR says to extract only files which are siblings
+      of that directory.  */
+   *should_be_written = list_only == 0;
+   if (*should_be_written &&
+       only_dir && strncmp(only_dir, name_to_change, strlen(only_dir)))
+     *should_be_written = 0;
+ 
+   changed_name = get_entry(name_to_change);
+   if (*should_be_written && !to_stdout && NO_LFN(changed_name))
+   {
+     replace_multiple_dots_in_path(changed_name);
+     strcpy(new, changed_name);
+     replace_illegal_chars(changed_name);
+     if (*basename(changed_name) != NULL)
+     {
+       if (strstr(changed_name, ".tar."))
+         replace_archive_extensions(changed_name);
+       if (strstr(changed_name, ".info"))
+         if (replace_info_extension(changed_name))
+           goto leave; /* let the user decide. */
+       if (strcmp (new, changed_name) != NULL)
+         fprintf(log_out, "[ changing %s to %s ]\n", new, changed_name);
+       if (dot_switch)
+         rename_special_files(changed_name);
+     }
+   }
+ leave:
    return changed_name;
  }
  

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019