LCOV - code coverage report
Current view: top level - src - create.c (source / functions) Hit Total Coverage
Test: cov.info Lines: 39 145 26.9 %
Date: 2015-08-15 Functions: 1 3 33.3 %

          Line data    Source code
       1             : /*-
       2             :  * Copyright (c) 2011-2015 Baptiste Daroussin <bapt@FreeBSD.org>
       3             :  * Copyright (c) 2011-2012 Julien Laffaye <jlaffaye@FreeBSD.org>
       4             :  * Copyright (c) 2011 Will Andrews <will@FreeBSD.org>
       5             :  * Copyright (c) 2015 Matthew Seaman <matthew@FreeBSD.org>
       6             :  * All rights reserved.
       7             :  *
       8             :  * Redistribution and use in source and binary forms, with or without
       9             :  * modification, are permitted provided that the following conditions
      10             :  * are met:
      11             :  * 1. Redistributions of source code must retain the above copyright
      12             :  *    notice, this list of conditions and the following disclaimer
      13             :  *    in this position and unchanged.
      14             :  * 2. Redistributions in binary form must reproduce the above copyright
      15             :  *    notice, this list of conditions and the following disclaimer in the
      16             :  *    documentation and/or other materials provided with the distribution.
      17             :  *
      18             :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
      19             :  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
      20             :  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
      21             :  * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
      22             :  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
      23             :  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      24             :  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      25             :  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      26             :  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
      27             :  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      28             :  */
      29             : 
      30             : #ifdef HAVE_CONFIG_H
      31             : #include "pkg_config.h"
      32             : #endif
      33             : 
      34             : #include <sys/param.h>
      35             : #include <sys/queue.h>
      36             : 
      37             : #ifdef PKG_COMPAT
      38             : #include <sys/stat.h>
      39             : #include <sys/types.h>
      40             : #include <dirent.h>
      41             : #endif
      42             : 
      43             : #include <err.h>
      44             : #include <getopt.h>
      45             : #include <stdio.h>
      46             : #include <pkg.h>
      47             : #include <string.h>
      48             : #include <unistd.h>
      49             : #include <sysexits.h>
      50             : 
      51             : #include "pkgcli.h"
      52             : 
      53             : struct pkg_entry {
      54             :         struct pkg *pkg;
      55             :         STAILQ_ENTRY(pkg_entry) next;
      56             : };
      57             : 
      58             : STAILQ_HEAD(pkg_head, pkg_entry);
      59             : 
      60             : void
      61           0 : usage_create(void)
      62             : {
      63           0 :         fprintf(stderr, "Usage: pkg create [-Onqv] [-f format] [-o outdir] "
      64             :                 "[-p plist] [-r rootdir] -m metadatadir\n");
      65           0 :         fprintf(stderr, "Usage: pkg create [-Onqv] [-f format] [-o outdir] "
      66             :                 "[-r rootdir] -M manifest\n");
      67           0 :         fprintf(stderr, "       pkg create [-Ognqvx] [-f format] [-o outdir] "
      68             :                 "[-r rootdir] pkg-name ...\n");
      69           0 :         fprintf(stderr, "       pkg create [-Onqv] [-f format] [-o outdir] "
      70             :                 "[-r rootdir] -a\n\n");
      71           0 :         fprintf(stderr, "For more information see 'pkg help create'.\n");
      72           0 : }
      73             : 
      74             : static int
      75           0 : pkg_create_matches(int argc, char **argv, match_t match, pkg_formats fmt,
      76             :     const char * const outdir, bool overwrite)
      77             : {
      78           0 :         int i, ret = EPKG_OK, retcode = EPKG_OK;
      79           0 :         struct pkg *pkg = NULL;
      80           0 :         struct pkgdb *db = NULL;
      81           0 :         struct pkgdb_it *it = NULL;
      82           0 :         int query_flags = PKG_LOAD_DEPS | PKG_LOAD_FILES |
      83             :             PKG_LOAD_CATEGORIES | PKG_LOAD_DIRS | PKG_LOAD_SCRIPTS |
      84             :             PKG_LOAD_OPTIONS | PKG_LOAD_LICENSES |
      85             :             PKG_LOAD_USERS | PKG_LOAD_GROUPS | PKG_LOAD_SHLIBS_REQUIRED |
      86             :             PKG_LOAD_PROVIDES | PKG_LOAD_REQUIRES |
      87             :             PKG_LOAD_SHLIBS_PROVIDED | PKG_LOAD_ANNOTATIONS;
      88           0 :         struct pkg_head head = STAILQ_HEAD_INITIALIZER(head);
      89           0 :         struct pkg_entry *e = NULL;
      90             :         char pkgpath[MAXPATHLEN];
      91           0 :         const char *format = NULL;
      92             :         bool foundone;
      93             : 
      94           0 :         if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK) {
      95           0 :                 pkgdb_close(db);
      96           0 :                 return (EX_IOERR);
      97             :         }
      98             :         /* XXX: get rid of hardcoded timeouts */
      99           0 :         if (pkgdb_obtain_lock(db, PKGDB_LOCK_READONLY) != EPKG_OK) {
     100           0 :                 pkgdb_close(db);
     101           0 :                 warnx("Cannot get a read lock on a database, it is locked by another process");
     102           0 :                 return (EX_TEMPFAIL);
     103             :         }
     104             : 
     105           0 :         switch (fmt) {
     106             :         case TXZ:
     107           0 :                 format = "txz";
     108           0 :                 break;
     109             :         case TBZ:
     110           0 :                 format = "tbz";
     111           0 :                 break;
     112             :         case TGZ:
     113           0 :                 format = "tgz";
     114           0 :                 break;
     115             :         case TAR:
     116           0 :                 format = "tar";
     117           0 :                 break;
     118             :         }
     119             : 
     120           0 :         for (i = 0; i < argc || match == MATCH_ALL; i++) {
     121           0 :                 if (match == MATCH_ALL) {
     122           0 :                         printf("Loading the package list...\n");
     123           0 :                         if ((it = pkgdb_query(db, NULL, match)) == NULL)
     124           0 :                                 goto cleanup;
     125           0 :                         match = !MATCH_ALL;
     126             :                 } else
     127           0 :                         if ((it = pkgdb_query(db, argv[i], match)) == NULL)
     128           0 :                                 goto cleanup;
     129             : 
     130           0 :                 foundone = false;
     131           0 :                 while ((ret = pkgdb_it_next(it, &pkg, query_flags)) == EPKG_OK) {
     132           0 :                         if ((e = malloc(sizeof(struct pkg_entry))) == NULL)
     133           0 :                                 err(1, "malloc(pkg_entry)");
     134           0 :                         e->pkg = pkg;
     135           0 :                         pkg = NULL;
     136           0 :                         STAILQ_INSERT_TAIL(&head, e, next);
     137           0 :                         foundone = true;
     138             :                 }
     139           0 :                 if (!foundone) {
     140           0 :                         warnx("No installed package matching \"%s\" found\n",
     141           0 :                             argv[i]);
     142           0 :                         retcode++;
     143             :                 }
     144             : 
     145           0 :                 pkgdb_it_free(it);
     146           0 :                 if (ret != EPKG_END)
     147           0 :                         retcode++;
     148             :         }
     149             : 
     150           0 :         while (!STAILQ_EMPTY(&head)) {
     151           0 :                 e = STAILQ_FIRST(&head);
     152           0 :                 STAILQ_REMOVE_HEAD(&head, next);
     153             : 
     154           0 :                 if (!overwrite) {
     155           0 :                         pkg_snprintf(pkgpath, sizeof(pkgpath), "%S/%n-%v.%S",
     156             :                             outdir, e->pkg, e->pkg, format);
     157           0 :                         if (access(pkgpath, F_OK) == 0) {
     158           0 :                                 pkg_printf("%n-%v already packaged, skipping...\n",
     159             :                                     e->pkg, e->pkg);
     160           0 :                                 pkg_free(e->pkg);
     161           0 :                                 free(e);
     162           0 :                                 continue;
     163             :                         }
     164             :                 }
     165           0 :                 pkg_printf("Creating package for %n-%v\n", e->pkg, e->pkg);
     166           0 :                 if (pkg_create_installed(outdir, fmt, e->pkg) !=
     167             :                     EPKG_OK)
     168           0 :                         retcode++;
     169           0 :                 pkg_free(e->pkg);
     170           0 :                 free(e);
     171             :         }
     172             : 
     173             : cleanup:
     174           0 :         pkgdb_release_lock(db, PKGDB_LOCK_READONLY);
     175           0 :         pkgdb_close(db);
     176             : 
     177           0 :         return (retcode);
     178             : }
     179             : 
     180             : /*
     181             :  * options:
     182             :  * -x: regex
     183             :  * -g: globbing
     184             :  * -r: rootdir for the package
     185             :  * -m: path to dir where to find the metadata
     186             :  * -q: quiet mode
     187             :  * -M: manifest file
     188             :  * -f <format>: format could be txz, tgz, tbz or tar
     189             :  * -o: output directory where to create packages by default ./ is used
     190             :  */
     191             : 
     192             : int
     193          66 : exec_create(int argc, char **argv)
     194             : {
     195          66 :         match_t          match = MATCH_EXACT;
     196          66 :         const char      *outdir = NULL;
     197          66 :         const char      *format = NULL;
     198          66 :         const char      *rootdir = NULL;
     199          66 :         const char      *metadatadir = NULL;
     200          66 :         const char      *manifest = NULL;
     201          66 :         char            *plist = NULL;
     202             :         pkg_formats      fmt;
     203             :         int              ch;
     204          66 :         bool             overwrite = true;
     205             : 
     206             : 
     207             :         /* POLA: pkg create is quiet by default, unless
     208             :          * PKG_CREATE_VERBOSE is set in pkg.conf.  This is for
     209             :          * historical reasons. */
     210             : 
     211          66 :         quiet = !pkg_object_bool(pkg_config_get("PKG_CREATE_VERBOSE"));
     212             : 
     213          66 :         struct option longopts[] = {
     214             :                 { "all",      no_argument,            NULL,   'a' },
     215             :                 { "glob",     no_argument,            NULL,   'g' },
     216             :                 { "regex",    no_argument,            NULL,   'x' },
     217             :                 { "format",   required_argument,      NULL,   'f' },
     218             :                 { "root-dir", required_argument,      NULL,   'r' },
     219             :                 { "metadata", required_argument,      NULL,   'm' },
     220             :                 { "manifest", required_argument,      NULL,   'M' },
     221             :                 { "out-dir",  required_argument,      NULL,   'o' },
     222             :                 { "no-clobber", no_argument,          NULL,   'n' },
     223             :                 { "plist",    required_argument,      NULL,   'p' },
     224             :                 { "quiet",    no_argument,            NULL,   'q' },
     225             :                 { "verbose",  no_argument,            NULL,   'v' },
     226             :                 { NULL,         0,                      NULL,   0   },
     227             :         };
     228             : 
     229         279 :         while ((ch = getopt_long(argc, argv, "+agxf:r:m:M:o:np:qv", longopts, NULL)) != -1) {
     230         147 :                 switch (ch) {
     231             :                 case 'a':
     232           0 :                         match = MATCH_ALL;
     233           0 :                         break;
     234             :                 case 'g':
     235           0 :                         match = MATCH_GLOB;
     236           0 :                         break;
     237             :                 case 'x':
     238           0 :                         match = MATCH_REGEX;
     239           0 :                         break;
     240             :                 case 'f':
     241           0 :                         format = optarg;
     242           0 :                         break;
     243             :                 case 'o':
     244          29 :                         outdir = optarg;
     245          29 :                         break;
     246             :                 case 'r':
     247          26 :                         rootdir = optarg;
     248          26 :                         break;
     249             :                 case 'm':
     250          25 :                         metadatadir = optarg;
     251          25 :                         break;
     252             :                 case 'M':
     253          41 :                         manifest = optarg;
     254          41 :                         break;
     255             :                 case 'n':
     256           0 :                         overwrite = false;
     257           0 :                         break;
     258             :                 case 'p':
     259          25 :                         plist = optarg;
     260          25 :                         break;
     261             :                 case 'q':
     262           1 :                         quiet = true;
     263           1 :                         break;
     264             :                 case 'v':
     265           0 :                         quiet = false;
     266           0 :                         break;
     267             :                 default:
     268           0 :                         usage_create();
     269           0 :                         return (EX_USAGE);
     270             :                 }
     271             :         }
     272          66 :         argc -= optind;
     273          66 :         argv += optind;
     274             : 
     275          66 :         if (match != MATCH_ALL && metadatadir == NULL && manifest == NULL &&
     276             :             argc == 0) {
     277           0 :                 usage_create();
     278           0 :                 return (EX_USAGE);
     279             :         }
     280             : 
     281          66 :         if (metadatadir == NULL && manifest == NULL && rootdir != NULL) {
     282           0 :                 warnx("Do not specify a rootdir without also specifying "
     283             :                     "either a metadatadir or manifest");
     284           0 :                 usage_create();
     285           0 :                 return (EX_USAGE);
     286             :         }
     287             : 
     288          66 :         if (outdir == NULL)
     289          37 :                 outdir = "./";
     290             : 
     291          66 :         if (format == NULL) {
     292          66 :                 fmt = TXZ;
     293             :         } else {
     294           0 :                 if (format[0] == '.')
     295           0 :                         ++format;
     296           0 :                 if (strcmp(format, "txz") == 0)
     297           0 :                         fmt = TXZ;
     298           0 :                 else if (strcmp(format, "tbz") == 0)
     299           0 :                         fmt = TBZ;
     300           0 :                 else if (strcmp(format, "tgz") == 0)
     301           0 :                         fmt = TGZ;
     302           0 :                 else if (strcmp(format, "tar") == 0)
     303           0 :                         fmt = TAR;
     304             :                 else {
     305           0 :                         warnx("unknown format %s, using txz", format);
     306           0 :                         fmt = TXZ;
     307             :                 }
     308             :         }
     309             : 
     310          66 :         if (metadatadir == NULL && manifest == NULL) {
     311           0 :                 return (pkg_create_matches(argc, argv, match, fmt, outdir,
     312           0 :                     overwrite) == EPKG_OK ? EX_OK : EX_SOFTWARE);
     313          66 :         } else if (metadatadir != NULL) {
     314          50 :                 return (pkg_create_staged(outdir, fmt, rootdir, metadatadir,
     315          25 :                     plist) == EPKG_OK ? EX_OK : EX_SOFTWARE);
     316             :         } else  { /* (manifest != NULL) */
     317          82 :                 return (pkg_create_from_manifest(outdir, fmt, rootdir,
     318          41 :                     manifest, plist) == EPKG_OK ? EX_OK : EX_SOFTWARE);
     319             :         }
     320             : }
     321             : 

Generated by: LCOV version 1.10