LCOV - code coverage report
Current view: top level - libpkg - packing.c (source / functions) Hit Total Coverage
Test: plop Lines: 224 287 78.0 %
Date: 2024-12-30 07:09:03 Functions: 9 9 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 120 158 75.9 %

           Branch data     Line data    Source code
       1                 :            : /*-
       2                 :            :  * Copyright (c) 2011-2021 Baptiste Daroussin <bapt@FreeBSD.org>
       3                 :            :  * Copyright (c) 2011 Will Andrews <will@FreeBSD.org>
       4                 :            :  * All rights reserved.
       5                 :            :  *
       6                 :            :  * Redistribution and use in source and binary forms, with or without
       7                 :            :  * modification, are permitted provided that the following conditions
       8                 :            :  * are met:
       9                 :            :  * 1. Redistributions of source code must retain the above copyright
      10                 :            :  *    notice, this list of conditions and the following disclaimer
      11                 :            :  *    in this position and unchanged.
      12                 :            :  * 2. Redistributions in binary form must reproduce the above copyright
      13                 :            :  *    notice, this list of conditions and the following disclaimer in the
      14                 :            :  *    documentation and/or other materials provided with the distribution.
      15                 :            :  *
      16                 :            :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
      17                 :            :  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
      18                 :            :  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
      19                 :            :  * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
      20                 :            :  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
      21                 :            :  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      22                 :            :  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      23                 :            :  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      24                 :            :  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
      25                 :            :  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      26                 :            :  */
      27                 :            : 
      28                 :            : #include <sys/uio.h>
      29                 :            : 
      30                 :            : #include <archive.h>
      31                 :            : #include <archive_entry.h>
      32                 :            : #include <assert.h>
      33                 :            : #include <bsd_compat.h>
      34                 :            : #include <fcntl.h>
      35                 :            : #include <fts.h>
      36                 :            : #include <string.h>
      37                 :            : #include <pwd.h>
      38                 :            : #include <grp.h>
      39                 :            : #include <errno.h>
      40                 :            : 
      41                 :            : #include "pkg.h"
      42                 :            : #include "private/event.h"
      43                 :            : #include "private/pkg.h"
      44                 :            : #include "private/packing.h"
      45                 :            : 
      46                 :            : #define dbg(x, ...) pkg_dbg(PKG_DBG_PACKING, x, __VA_ARGS__);
      47                 :            : 
      48                 :            : int
      49                 :        416 : packing_init(struct packing **pack, const char *path, pkg_formats format, int clevel,
      50                 :            :         int threads, time_t timestamp, bool overwrite, bool compat_symlink)
      51                 :            : {
      52                 :            :         char archive_path[MAXPATHLEN];
      53                 :            :         char archive_symlink[MAXPATHLEN];
      54                 :            :         char *archive_name;
      55                 :            :         const char *ext;
      56                 :            :         const char *source_date_epoch;
      57                 :            :         char *endptr;
      58                 :            :         time_t ts;
      59                 :            : 
      60         [ +  - ]:        416 :         assert(pack != NULL);
      61                 :            : 
      62                 :        416 :         *pack = xcalloc(1, sizeof(struct packing));
      63                 :        416 :         (*pack)->timestamp = timestamp;
      64                 :            : 
      65   [ +  +  +  + ]:        416 :         if ((*pack)->timestamp == (time_t)-1 &&
      66                 :        414 :                 (source_date_epoch = getenv("SOURCE_DATE_EPOCH")) != NULL) {
      67                 :          1 :                         ts = (time_t)strtoimax(source_date_epoch, &endptr, 10);
      68         [ -  + ]:          1 :                         if (*endptr != '\0') {
      69                 :          0 :                                 pkg_emit_error("Ignoring bad environment variable "
      70                 :          0 :                                     "SOURCE_DATE_EPOCH: %s", source_date_epoch);
      71                 :          0 :                         } else {
      72                 :          1 :                                 (*pack)->timestamp = ts;
      73                 :            :                         }
      74                 :          1 :         }
      75                 :            : 
      76                 :        416 :         (*pack)->aread = archive_read_disk_new();
      77                 :        416 :         archive_read_disk_set_standard_lookup((*pack)->aread);
      78                 :        416 :         archive_read_disk_set_symlink_physical((*pack)->aread);
      79                 :            : 
      80                 :        416 :         (*pack)->awrite = archive_write_new();
      81                 :        416 :         archive_write_set_format_pax_restricted((*pack)->awrite);
      82                 :        416 :         ext = packing_set_format((*pack)->awrite, format, clevel, threads);
      83         [ +  - ]:        416 :         if (ext == NULL) {
      84                 :          0 :                 archive_read_close((*pack)->aread);
      85                 :          0 :                 archive_read_free((*pack)->aread);
      86                 :          0 :                 archive_write_close((*pack)->awrite);
      87                 :          0 :                 archive_write_free((*pack)->awrite);
      88                 :          0 :                 free(*pack);
      89                 :          0 :                 *pack = NULL;
      90                 :          0 :                 return (EPKG_FATAL); /* error set by _set_format() */
      91                 :            :         }
      92                 :        416 :         snprintf(archive_path, sizeof(archive_path), "%s.pkg", path);
      93                 :        416 :         archive_name = strrchr(archive_path, '/');
      94         [ +  - ]:        416 :         if (archive_name == NULL)
      95                 :          0 :                 archive_name = archive_path;
      96                 :            :         else
      97                 :        416 :                 archive_name++;
      98                 :        832 :         snprintf(archive_symlink, sizeof(archive_path), "%s.%s", path,
      99                 :        416 :             ext);
     100                 :            : 
     101   [ +  +  -  + ]:        416 :         if (!overwrite && access(archive_path, F_OK) == 0) {
     102                 :          1 :                 archive_read_close((*pack)->aread);
     103                 :          1 :                 archive_read_free((*pack)->aread);
     104                 :          1 :                 archive_write_close((*pack)->awrite);
     105                 :          1 :                 archive_write_free((*pack)->awrite);
     106                 :          1 :                 free(*pack);
     107                 :          1 :                 *pack = NULL;
     108                 :          1 :                 errno = EEXIST;
     109                 :          1 :                 return (EPKG_EXIST);
     110                 :            :         }
     111                 :        415 :         dbg(1, "target file '%s'", archive_path);
     112   [ -  +  -  + ]:        830 :         if (archive_write_open_filename(
     113                 :        830 :             (*pack)->awrite, archive_path) != ARCHIVE_OK) {
     114                 :          0 :                 pkg_emit_errno("archive_write_open_filename",
     115                 :          0 :                     archive_path);
     116                 :          0 :                 archive_read_close((*pack)->aread);
     117                 :          0 :                 archive_read_free((*pack)->aread);
     118                 :          0 :                 archive_write_close((*pack)->awrite);
     119                 :          0 :                 archive_write_free((*pack)->awrite);
     120                 :          0 :                 *pack = NULL;
     121                 :          0 :                 return EPKG_FATAL;
     122                 :            :         }
     123                 :            : 
     124   [ +  +  -  + ]:        415 :         if (compat_symlink || ctx.archive_symlink) {
     125                 :        151 :                 unlink(archive_symlink);
     126         [ +  - ]:        151 :                 if (symlink(archive_name, archive_symlink) != 0) {
     127                 :          0 :                         pkg_emit_errno("symlink", archive_symlink);
     128                 :          0 :                 }
     129                 :        151 :         }
     130                 :            : 
     131                 :        415 :         (*pack)->resolver = archive_entry_linkresolver_new();
     132                 :        830 :         archive_entry_linkresolver_set_strategy((*pack)->resolver,
     133                 :        415 :             archive_format((*pack)->awrite));
     134                 :            : 
     135                 :        415 :         return (EPKG_OK);
     136                 :        416 : }
     137                 :            : 
     138                 :            : int
     139                 :        546 : packing_append_iovec(struct packing *pack, const char *path, struct iovec *iov,
     140                 :            :     int niov)
     141                 :            : {
     142                 :            :         struct archive_entry *entry;
     143                 :        546 :         int ret = EPKG_OK, size = 0;
     144                 :            : 
     145                 :        546 :         dbg(1, "adding file '%s'", path);
     146         [ +  + ]:       1100 :         for (int idx = 0; idx < niov; idx++) {
     147                 :        554 :                 size += iov[idx].iov_len;
     148                 :        554 :         }
     149                 :        546 :         entry = archive_entry_new();
     150                 :        546 :         archive_entry_clear(entry);
     151                 :        546 :         archive_entry_set_filetype(entry, AE_IFREG);
     152                 :        546 :         archive_entry_set_perm(entry, 0644);
     153                 :        546 :         archive_entry_set_gname(entry, "wheel");
     154                 :        546 :         archive_entry_set_uname(entry, "root");
     155                 :        546 :         archive_entry_set_pathname(entry, path);
     156                 :        546 :         archive_entry_set_size(entry, size);
     157         [ +  - ]:        546 :         if (archive_write_header(pack->awrite, entry) == -1) {
     158                 :          0 :                 pkg_emit_errno("archive_write_header", path);
     159                 :          0 :                 ret = EPKG_FATAL;
     160                 :          0 :                 goto cleanup;
     161                 :            :         }
     162                 :            : 
     163         [ +  + ]:       1100 :         for (int idx = 0; idx < niov; idx++) {
     164                 :            :                 const char *buffer;
     165                 :            : 
     166                 :        554 :                 buffer = iov[idx].iov_base;
     167                 :        554 :                 size = iov[idx].iov_len;
     168         [ +  - ]:        554 :                 if (archive_write_data(pack->awrite, buffer, size) == -1) {
     169                 :          0 :                         pkg_emit_errno("archive_write_data", path);
     170                 :          0 :                         ret = EPKG_FATAL;
     171                 :          0 :                 }
     172                 :       1100 :         }
     173                 :            : 
     174                 :            : cleanup:
     175                 :        546 :         archive_entry_free(entry);
     176                 :            : 
     177                 :        546 :         return (ret);
     178                 :            : }
     179                 :            : 
     180                 :            : int
     181                 :        526 : packing_append_buffer(struct packing *pack, const char *buffer,
     182                 :            :     const char *path, int size)
     183                 :            : {
     184                 :            :         struct iovec iov;
     185                 :            : 
     186                 :        526 :         dbg(1, "adding file '%s'", path);
     187                 :        526 :         iov.iov_base = __DECONST(char *, buffer);
     188                 :        526 :         iov.iov_len = size;
     189                 :        526 :         return (packing_append_iovec(pack, path, &iov, 1));
     190                 :            : }
     191                 :            : 
     192                 :            : int
     193                 :        371 : packing_append_file_attr(struct packing *pack, const char *filepath,
     194                 :            :     const char *newpath, const char *uname, const char *gname, mode_t perm,
     195                 :            :     u_long fflags)
     196                 :            : {
     197                 :            :         int fd;
     198                 :        371 :         int retcode = EPKG_OK;
     199                 :            :         int ret;
     200                 :            :         struct stat st;
     201                 :            :         struct archive_entry *entry, *sparse_entry;
     202                 :            :         bool unset_timestamp;
     203                 :            :         char buf[32768];
     204                 :            :         int len;
     205                 :            : 
     206                 :        371 :         entry = archive_entry_new();
     207                 :        371 :         archive_entry_copy_sourcepath(entry, filepath);
     208                 :            : 
     209                 :        371 :         dbg(1, "adding file '%s'", filepath);
     210                 :            : 
     211         [ -  + ]:        371 :         if (lstat(filepath, &st) != 0) {
     212                 :          0 :                 pkg_emit_errno("lstat", filepath);
     213                 :          0 :                 retcode = EPKG_FATAL;
     214                 :          0 :                 goto cleanup;
     215                 :            :         }
     216                 :            : 
     217                 :        371 :         ret = archive_read_disk_entry_from_file(pack->aread, entry, -1,
     218                 :            :                         &st);
     219         [ -  + ]:        371 :         if (ret != ARCHIVE_OK) {
     220                 :          0 :                 pkg_emit_error("%s: %s", filepath,
     221                 :          0 :                                 archive_error_string(pack->aread));
     222                 :          0 :                 retcode = EPKG_FATAL;
     223                 :          0 :                 goto cleanup;
     224                 :            :         }
     225                 :            : 
     226         [ -  + ]:        371 :         if (newpath != NULL)
     227                 :        371 :                 archive_entry_set_pathname(entry, newpath);
     228                 :            : 
     229         [ +  + ]:        371 :         if (archive_entry_filetype(entry) != AE_IFREG) {
     230                 :         19 :                 archive_entry_set_size(entry, 0);
     231                 :         19 :         }
     232                 :            : 
     233   [ +  -  +  + ]:        371 :         if (uname != NULL && uname[0] != '\0') {
     234                 :        227 :                 archive_entry_set_uname(entry, uname);
     235                 :        227 :         }
     236                 :            : 
     237   [ +  -  +  + ]:        371 :         if (gname != NULL && gname[0] != '\0') {
     238                 :        227 :                 archive_entry_set_gname(entry, gname);
     239                 :        227 :         }
     240                 :            : 
     241         [ +  + ]:        371 :         if (fflags > 0)
     242                 :          1 :                 archive_entry_set_fflags(entry, fflags, 0);
     243                 :            : 
     244         [ +  + ]:        371 :         if (perm != 0)
     245                 :        177 :                 archive_entry_set_perm(entry, perm);
     246                 :            : 
     247                 :        371 :         unset_timestamp = pkg_object_bool(pkg_config_get("UNSET_TIMESTAMP"));
     248                 :            : 
     249         [ +  - ]:        371 :         if (unset_timestamp) {
     250                 :          0 :                 archive_entry_unset_atime(entry);
     251                 :          0 :                 archive_entry_unset_ctime(entry);
     252                 :          0 :                 archive_entry_unset_mtime(entry);
     253                 :          0 :                 archive_entry_unset_birthtime(entry);
     254                 :          0 :         }
     255                 :            : 
     256         [ +  + ]:        371 :         if (pack->timestamp != (time_t) -1) {
     257                 :          3 :                 archive_entry_set_atime(entry, pack->timestamp, 0);
     258                 :          3 :                 archive_entry_set_ctime(entry, pack->timestamp, 0);
     259                 :          3 :                 archive_entry_set_mtime(entry, pack->timestamp, 0);
     260                 :          3 :                 archive_entry_set_birthtime(entry, pack->timestamp, 0);
     261                 :          3 :         }
     262                 :            : 
     263                 :        371 :         archive_entry_linkify(pack->resolver, &entry, &sparse_entry);
     264                 :            : 
     265   [ -  +  #  # ]:        371 :         if (sparse_entry != NULL && entry == NULL)
     266                 :          0 :                 entry = sparse_entry;
     267                 :            : 
     268                 :        371 :         archive_write_header(pack->awrite, entry);
     269                 :            : 
     270         [ +  + ]:        371 :         if (archive_entry_size(entry) <= 0)
     271                 :        135 :                 goto cleanup;
     272                 :            : 
     273         [ +  - ]:        236 :         if ((fd = open(filepath, O_RDONLY)) < 0) {
     274                 :          0 :                 pkg_emit_errno("open", filepath);
     275                 :          0 :                 retcode = EPKG_FATAL;
     276                 :          0 :                 goto cleanup;
     277                 :            :         }
     278                 :            : 
     279         [ +  + ]:        487 :         while ((len = read(fd, buf, sizeof(buf))) > 0) {
     280         [ -  + ]:        251 :                 if (archive_write_data(pack->awrite, buf, len) == -1) {
     281                 :          0 :                         pkg_emit_errno("archive_write_data", "archive write error");
     282                 :          0 :                         retcode = EPKG_FATAL;
     283                 :          0 :                         break;
     284                 :            :                 }
     285                 :            :         }
     286                 :            : 
     287         [ +  - ]:        236 :         if (len == -1) {
     288                 :          0 :                 pkg_emit_errno("read", "file read error");
     289                 :          0 :                 retcode = EPKG_FATAL;
     290                 :          0 :         }
     291                 :        236 :         close(fd);
     292                 :            : 
     293                 :            : cleanup:
     294                 :        371 :         archive_entry_free(entry);
     295                 :        371 :         return (retcode);
     296                 :            : }
     297                 :            : 
     298                 :            : void
     299                 :        415 : packing_finish(struct packing *pack)
     300                 :            : {
     301         [ +  - ]:        415 :         if (pack == NULL)
     302                 :          0 :                 return;
     303                 :            : 
     304                 :        415 :         archive_read_close(pack->aread);
     305                 :        415 :         archive_read_free(pack->aread);
     306                 :        415 :         archive_entry_linkresolver_free(pack->resolver);
     307                 :            : 
     308                 :        415 :         archive_write_close(pack->awrite);
     309                 :        415 :         archive_write_free(pack->awrite);
     310                 :            : 
     311                 :        415 :         free(pack);
     312                 :        415 : }
     313                 :            : 
     314                 :            : const char *
     315                 :        434 : packing_set_format(struct archive *a, pkg_formats format, int clevel, int threads)
     316                 :            : {
     317                 :        434 :         const char *notsupp_fmt = "%s is not supported, trying %s";
     318                 :        434 :         const char *notbltin_fmt = "%s is supported, but not builtin";
     319                 :            :         int error;
     320                 :            : 
     321                 :            :         pkg_formats elected_format;
     322                 :            : 
     323                 :            :         /*
     324                 :            :          * For several of these formats, ARCHIVE_WARN will be returned when an
     325                 :            :          * external program will be used to satisfy the request.
     326                 :            :          */
     327   [ +  +  +  +  :        434 :         switch (format) {
                   +  + ]
     328                 :            :         case TZS:
     329                 :            : #ifdef HAVE_ARCHIVE_WRITE_ADD_FILTER_ZSTD
     330                 :        416 :                 error = archive_write_add_filter_zstd(a);
     331         [ +  - ]:        416 :                 if (error == ARCHIVE_OK) {
     332                 :        416 :                         elected_format = TZS;
     333         [ +  + ]:        416 :                         if (clevel == -1)
     334                 :        263 :                                 clevel = 19;
     335                 :        416 :                         goto out;
     336         [ #  # ]:          0 :                 } else if (error == ARCHIVE_WARN) {
     337                 :          0 :                         pkg_emit_error(notbltin_fmt, "zstd");
     338                 :          0 :                         return (NULL);
     339                 :            :                 }
     340                 :            : #endif
     341                 :          5 :                 pkg_emit_error(notsupp_fmt, "zstd", "xz");
     342                 :            :                 /* FALLTHRU */
     343                 :            :         case TXZ:
     344         [ -  + ]:          5 :                 if (archive_write_add_filter_xz(a) == ARCHIVE_OK) {
     345                 :          5 :                         elected_format = TXZ;
     346                 :          5 :                         goto out;
     347                 :            :                 }
     348                 :          3 :                 pkg_emit_error(notsupp_fmt, "xz", "bzip2");
     349                 :            :                 /* FALLTHRU */
     350                 :            :         case TBZ:
     351                 :          3 :                 error = archive_write_add_filter_bzip2(a);
     352         [ -  + ]:          3 :                 if (error == ARCHIVE_OK) {
     353                 :          3 :                         elected_format = TBZ;
     354                 :          3 :                         goto out;
     355         [ #  # ]:          0 :                 } else if (error == ARCHIVE_WARN) {
     356                 :          0 :                         pkg_emit_error(notbltin_fmt, "bzip2");
     357                 :          0 :                         return (NULL);
     358                 :            :                 }
     359                 :          3 :                 pkg_emit_error(notsupp_fmt, "bzip2", "gzip");
     360                 :            :                 /* FALLTHRU */
     361                 :            :         case TGZ:
     362                 :          3 :                 error = archive_write_add_filter_gzip(a);
     363         [ -  + ]:          3 :                 if (error == ARCHIVE_OK) {
     364                 :          3 :                         elected_format = TGZ;
     365                 :          3 :                         goto out;
     366         [ #  # ]:          0 :                 } else if (error == ARCHIVE_WARN) {
     367                 :          0 :                         pkg_emit_error(notbltin_fmt, "gzip");
     368                 :          0 :                         return (NULL);
     369                 :            :                 }
     370                 :          4 :                 pkg_emit_error(notsupp_fmt, "gzip", "plain tar");
     371                 :            :                 /* FALLTHRU */
     372                 :            :         case TAR:
     373                 :          4 :                 archive_write_add_filter_none(a);
     374                 :          4 :                 elected_format = TAR;
     375                 :          4 :                 break;
     376                 :            :         default:
     377                 :          3 :                 return (NULL);
     378                 :          4 :         }
     379                 :            : 
     380                 :            : out:
     381         [ +  + ]:        431 :         if (clevel == -1)
     382                 :          7 :                 clevel = 0;
     383                 :            :         /*
     384                 :            :          * N.B., we only want to whine about this if the user actually selected
     385                 :            :          * tar and specified a compress level.  If we had to fallback to tar,
     386                 :            :          * that's not the user's fault.
     387                 :            :          */
     388   [ +  +  +  + ]:        431 :         if (format == TAR && clevel != 0)
     389                 :          2 :                 pkg_emit_error("Plain tar and a compression level does not make sense");
     390                 :            : 
     391         [ +  + ]:        431 :         if (elected_format != TAR) {
     392                 :            :                 char buf[16];
     393         [ +  + ]:        427 :                 if (clevel != 0) {
     394                 :            :                         /*
     395                 :            :                          * A bit of a kludge but avoids dragging in headers for all of
     396                 :            :                          * these libraries.
     397                 :            :                          */
     398         [ +  + ]:        271 :                         if (clevel == INT_MIN) {
     399   [ -  +  +  +  :          4 :                                 switch (elected_format) {
                      + ]
     400                 :            :                                         case TZS:
     401                 :          1 :                                                 clevel = -5;
     402                 :          4 :                                                 break;
     403                 :            :                                         case TXZ:
     404                 :            :                                         case TBZ:
     405                 :            :                                         case TGZ:
     406                 :          3 :                                                 clevel = 1;
     407                 :          3 :                                                 break;
     408                 :            :                                         default:
     409                 :          0 :                                                 __unreachable();
     410                 :            :                                 }
     411         [ +  + ]:        271 :                         } else if (clevel == INT_MAX) {
     412   [ -  +  +  +  :          4 :                                 switch (elected_format) {
                      + ]
     413                 :            :                                         case TZS:
     414                 :          1 :                                                 clevel = 19;
     415                 :          4 :                                                 break;
     416                 :            :                                         case TXZ:
     417                 :            :                                         case TBZ:
     418                 :            :                                         case TGZ:
     419                 :          3 :                                                 clevel = 9;
     420                 :          3 :                                                 break;
     421                 :            :                                         default:
     422                 :          0 :                                                 __unreachable();
     423                 :            :                                 }
     424                 :          4 :                         }
     425                 :            : 
     426                 :        271 :                         snprintf(buf, sizeof(buf), "%d", clevel);
     427         [ +  - ]:        271 :                         if (archive_write_set_filter_option(a, NULL, "compression-level", buf) != ARCHIVE_OK)
     428                 :          0 :                                 pkg_emit_error("bad compression-level %d", clevel);
     429                 :        271 :                 }
     430         [ +  + ]:        427 :                 if (threads >= 0) {
     431                 :        151 :                         snprintf(buf, sizeof(buf), "%d", threads);
     432         [ +  - ]:        151 :                         if (archive_write_set_filter_option(a, NULL, "threads", buf) != ARCHIVE_OK)
     433                 :          0 :                                 pkg_emit_error("bad threads value %d", threads);
     434                 :        151 :                 }
     435                 :        427 :         }
     436                 :            : 
     437                 :        431 :         return (packing_format_to_string(elected_format));
     438                 :        434 : }
     439                 :            : 
     440                 :            : pkg_formats
     441                 :        597 : packing_format_from_string(const char *str)
     442                 :            : {
     443         [ +  + ]:        597 :         if (str == NULL)
     444                 :        282 :                 return DEFAULT_COMPRESSION;
     445         [ +  + ]:        315 :         if (STREQ(str, "tzst"))
     446                 :        310 :                 return TZS;
     447         [ +  + ]:          5 :         if (STREQ(str, "txz"))
     448                 :          1 :                 return TXZ;
     449         [ +  + ]:          4 :         if (STREQ(str, "tbz"))
     450                 :          1 :                 return TBZ;
     451         [ +  + ]:          3 :         if (STREQ(str, "tgz"))
     452                 :          1 :                 return TGZ;
     453         [ +  + ]:          2 :         if (STREQ(str, "tar"))
     454                 :          1 :                 return TAR;
     455                 :          1 :         pkg_emit_error("unknown format %s, using txz", str);
     456                 :          1 :         return TXZ;
     457                 :        597 : }
     458                 :            : 
     459                 :            : bool
     460                 :        446 : packing_is_valid_format(const char *str)
     461                 :            : {
     462         [ +  + ]:        446 :         if (str == NULL)
     463                 :          1 :                 return (false);
     464   [ +  +  +  + ]:        724 :         if (STREQ(str, "pkg") ||
     465         [ +  + ]:        283 :             STREQ(str, "tzst") ||
     466         [ +  + ]:        282 :             STREQ(str, "txz") ||
     467         [ +  + ]:        281 :             STREQ(str, "tbz") ||
     468         [ +  + ]:        280 :             STREQ(str, "tgz") ||
     469                 :        279 :             STREQ(str, "tar"))
     470                 :        167 :             return (true);
     471                 :        278 :         return (false);
     472                 :        446 : }
     473                 :            : 
     474                 :            : const char*
     475                 :        747 : packing_format_to_string(pkg_formats format)
     476                 :            : {
     477                 :        747 :         const char *res = NULL;
     478                 :            : 
     479   [ +  +  +  +  :        747 :         switch (format) {
                   +  + ]
     480                 :            :         case TZS:
     481                 :        727 :                 res = "tzst";
     482                 :        727 :                 break;
     483                 :            :         case TXZ:
     484                 :          6 :                 res = "txz";
     485                 :          6 :                 break;
     486                 :            :         case TBZ:
     487                 :          4 :                 res = "tbz";
     488                 :          4 :                 break;
     489                 :            :         case TGZ:
     490                 :          4 :                 res = "tgz";
     491                 :          4 :                 break;
     492                 :            :         case TAR:
     493                 :          5 :                 res = "tar";
     494                 :          5 :                 break;
     495                 :            :         }
     496                 :            : 
     497                 :        747 :         return (res);
     498                 :            : }

Generated by: LCOV version 1.15