(root)/
tar-1.35/
src/
suffix.c
       1  /* This file is part of GNU tar.
       2     Copyright 2007-2023 Free Software Foundation, Inc.
       3  
       4     Written by Sergey Poznyakoff.
       5  
       6     GNU tar is free software; you can redistribute it and/or modify it
       7     under the terms of the GNU General Public License as published by the
       8     Free Software Foundation; either version 3, or (at your option) any later
       9     version.
      10  
      11     GNU tar is distributed in the hope that it will be useful, but
      12     WITHOUT ANY WARRANTY; without even the implied warranty of
      13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
      14     Public License for more details.
      15  
      16     You should have received a copy of the GNU General Public License along
      17     with GNU tar.  If not, see <http://www.gnu.org/licenses/>.  */
      18  
      19  #include <system.h>
      20  #include "common.h"
      21  
      22  struct compression_suffix
      23  {
      24    const char *suffix;
      25    size_t length;
      26    const char *program;
      27  };
      28  
      29  static struct compression_suffix compression_suffixes[] = {
      30  #define __CAT2__(a,b) a ## b
      31  #define S(s,p) #s, sizeof (#s) - 1, __CAT2__(p,_PROGRAM)
      32    { "tar", 3, NULL },
      33    { S(gz,   GZIP) },
      34    { S(tgz,  GZIP) },
      35    { S(taz,  GZIP) },
      36    { S(Z,    COMPRESS) },
      37    { S(taZ,  COMPRESS) },
      38    { S(bz2,  BZIP2) },
      39    { S(tbz,  BZIP2) },
      40    { S(tbz2, BZIP2) },
      41    { S(tz2,  BZIP2) },
      42    { S(lz,   LZIP) },
      43    { S(lzma, LZMA) },
      44    { S(tlz,  LZMA) },
      45    { S(lzo,  LZOP) },
      46    { S(xz,   XZ) },
      47    { S(txz,  XZ) }, /* Slackware */
      48    { S(zst,  ZSTD) },
      49    { S(tzst, ZSTD) },
      50    { NULL }
      51  #undef S
      52  #undef __CAT2__
      53  };
      54  
      55  static struct compression_suffix const *
      56  find_compression_suffix (const char *name, size_t *ret_len)
      57  {
      58    char *suf = strrchr (name, '.');
      59  
      60    if (suf)
      61      {
      62        size_t len;
      63        struct compression_suffix *p;
      64  
      65        suf++;
      66        len = strlen (suf);
      67  
      68        for (p = compression_suffixes; p->suffix; p++)
      69  	{
      70  	  if (p->length == len && memcmp (p->suffix, suf, len) == 0)
      71  	    {
      72  	      if (ret_len)
      73  		*ret_len = strlen (name) - len - 1;
      74  	      return p;
      75  	    }
      76  	}
      77      }
      78    return NULL;
      79  }
      80  
      81  static const char *
      82  find_compression_program (const char *name, const char *defprog)
      83  {
      84    struct compression_suffix const *p = find_compression_suffix (name, NULL);
      85    if (p)
      86      return p->program;
      87    return defprog;
      88  }
      89  
      90  void
      91  set_compression_program_by_suffix (const char *name, const char *defprog)
      92  {
      93    const char *program = find_compression_program (name, defprog);
      94    if (program)
      95      use_compress_program_option = program;
      96  }
      97  
      98  char *
      99  strip_compression_suffix (const char *name)
     100  {
     101    char *s = NULL;
     102    size_t len;
     103    struct compression_suffix const *p = find_compression_suffix (name, &len);
     104  
     105    if (p)
     106      {
     107        /* Strip an additional ".tar" suffix, but only if the just-stripped
     108  	 "outer" suffix did not begin with "t".  */
     109        if (len > 4 && strncmp (name + len - 4, ".tar", 4) == 0
     110  	  && p->suffix[0] != 't')
     111  	len -= 4;
     112        if (len == 0)
     113  	return NULL;
     114        s = xmalloc (len + 1);
     115        memcpy (s, name, len);
     116        s[len] = 0;
     117      }
     118    return s;
     119  }