LCOV - code coverage report
Current view: top level - src - add.c (source / functions) Hit Total Coverage
Test: cov.info Lines: 53 92 57.6 %
Date: 2015-08-15 Functions: 2 3 66.7 %

          Line data    Source code
       1             : /*-
       2             :  * Copyright (c) 2011-2012 Baptiste Daroussin <bapt@FreeBSD.org>
       3             :  * Copyright (c) 2011-2012 Julien Laffaye <jlaffaye@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/param.h>
      29             : #include <sys/sbuf.h>
      30             : 
      31             : #include <err.h>
      32             : #include <errno.h>
      33             : #include <libgen.h>
      34             : #include <stdio.h>
      35             : #include <string.h>
      36             : #include <sysexits.h>
      37             : #include <unistd.h>
      38             : #include <getopt.h>
      39             : 
      40             : #include <pkg.h>
      41             : 
      42             : #include "pkgcli.h"
      43             : 
      44             : static int
      45          20 : is_url(const char * const pattern)
      46             : {
      47          40 :         if (strncmp(pattern, "http://", 7) == 0 ||
      48          40 :                 strncmp(pattern, "https://", 8) == 0 ||
      49          40 :                 strncmp(pattern, "ftp://", 6) == 0 ||
      50          20 :                 strncmp(pattern, "file://", 7) == 0)
      51           0 :                 return (EPKG_OK);
      52             : 
      53          20 :         return (EPKG_FATAL);
      54             : }
      55             : 
      56             : void
      57           0 : usage_add(void)
      58             : {
      59           0 :         fprintf(stderr, "Usage: pkg add [-IAfqM] <pkg-name> ...\n");
      60           0 :         fprintf(stderr, "       pkg add [-IAfqM] <protocol>://<path>/<pkg-name> ...\n\n");
      61           0 :         fprintf(stderr, "For more information see 'pkg help add'.\n");
      62           0 : }
      63             : 
      64             : int
      65          10 : exec_add(int argc, char **argv)
      66             : {
      67          10 :         struct pkgdb *db = NULL;
      68          10 :         struct sbuf *failedpkgs = NULL;
      69             :         char path[MAXPATHLEN];
      70             :         char *file;
      71             :         int retcode;
      72             :         int ch;
      73             :         int i;
      74          10 :         int failedpkgcount = 0;
      75          10 :         pkg_flags f = PKG_FLAG_NONE;
      76          10 :         struct pkg_manifest_key *keys = NULL;
      77          10 :         const char *location = NULL;
      78             : 
      79             :         /* options descriptor */
      80          10 :         struct option longopts[] = {
      81             :                 { "no-scripts",          no_argument,            NULL,           'I' },
      82             :                 { "automatic",           no_argument,            NULL,           'A' },
      83             :                 { "force",               no_argument,            NULL,           'f' },
      84             :                 { "accept-missing",      no_argument,            NULL,           'M' },
      85             :                 { "quiet",               no_argument,            NULL,           'q' },
      86             :                 { "relocate",            required_argument,      NULL,            1  },
      87             :                 { NULL,                  0,                      NULL,            0  }
      88             :         };
      89             : 
      90          25 :         while ((ch = getopt_long(argc, argv, "+IAfqM", longopts, NULL)) != -1) {
      91           5 :                 switch (ch) {
      92             :                 case 'I':
      93           1 :                         f |= PKG_ADD_NOSCRIPT;
      94           1 :                         break;
      95             :                 case 'A':
      96           1 :                         f |= PKG_ADD_AUTOMATIC;
      97           1 :                         break;
      98             :                 case 'f':
      99           0 :                         f |= PKG_ADD_FORCE;
     100           0 :                         force = true;
     101           0 :                         break;
     102             :                 case 'M':
     103           2 :                         f |= PKG_ADD_FORCE_MISSING;
     104           2 :                         break;
     105             :                 case 'q':
     106           1 :                         quiet = true;
     107           1 :                         break;
     108             :                 case 1:
     109           0 :                         location = optarg;
     110           0 :                         break;
     111             :                 default:
     112           0 :                         usage_add();
     113           0 :                         return (EX_USAGE);
     114             :                 }
     115             :         }
     116          10 :         argc -= optind;
     117          10 :         argv += optind;
     118             : 
     119          10 :         if (argc < 1) {
     120           0 :                 usage_add();
     121           0 :                 return (EX_USAGE);
     122             :         }
     123             : 
     124          10 :         retcode = pkgdb_access(PKGDB_MODE_READ  |
     125             :                                PKGDB_MODE_WRITE |
     126             :                                PKGDB_MODE_CREATE,
     127             :                                PKGDB_DB_LOCAL);
     128          10 :         if (retcode == EPKG_ENOACCESS) {
     129           0 :                 warnx("Insufficient privileges to add packages");
     130           0 :                 return (EX_NOPERM);
     131          10 :         } else if (retcode != EPKG_OK)
     132           0 :                 return (EX_IOERR);
     133             : 
     134          10 :         if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK)
     135           0 :                 return (EX_IOERR);
     136             : 
     137          10 :         if (pkgdb_obtain_lock(db, PKGDB_LOCK_EXCLUSIVE) != EPKG_OK) {
     138           0 :                 pkgdb_close(db);
     139           0 :                 warnx("Cannot get an exclusive lock on a database, it is locked by another process");
     140           0 :                 return (EX_TEMPFAIL);
     141             :         }
     142             : 
     143          10 :         failedpkgs = sbuf_new_auto();
     144          10 :         pkg_manifest_keys_new(&keys);
     145          20 :         for (i = 0; i < argc; i++) {
     146          10 :                 if (is_url(argv[i]) == EPKG_OK) {
     147           0 :                         snprintf(path, sizeof(path), "%s/%s.XXXXX",
     148           0 :                             getenv("TMPDIR") != NULL ? getenv("TMPDIR") : "/tmp", basename(argv[i]));
     149           0 :                         if ((retcode = pkg_fetch_file(NULL, argv[i], path, 0, 0, 0)) != EPKG_OK)
     150           0 :                                 break;
     151             : 
     152           0 :                         file = path;
     153             :                 } else {
     154          10 :                         file = argv[i];
     155             : 
     156             :                         /* Special case: treat a filename of "-" as
     157             :                            meaning 'read from stdin.'  It doesn't make
     158             :                            sense to have a filename of "-" more than
     159             :                            once per command line, but we aren't
     160             :                            testing for that at the moment */
     161             : 
     162          10 :                         if (strcmp(file, "-") != 0 && access(file, F_OK) != 0) {
     163           0 :                                 warn("%s", file);
     164           0 :                                 if (errno == ENOENT)
     165           0 :                                         warnx("Was 'pkg install %s' meant?", file);
     166           0 :                                 sbuf_cat(failedpkgs, argv[i]);
     167           0 :                                 if (i != argc - 1)
     168           0 :                                         sbuf_printf(failedpkgs, ", ");
     169           0 :                                 failedpkgcount++;
     170           0 :                                 continue;
     171             :                         }
     172             : 
     173             :                 }
     174             : 
     175          10 :                 if ((retcode = pkg_add(db, file, f, keys, location)) != EPKG_OK) {
     176           2 :                         sbuf_cat(failedpkgs, argv[i]);
     177           2 :                         if (i != argc - 1)
     178           0 :                                 sbuf_printf(failedpkgs, ", ");
     179           2 :                         failedpkgcount++;
     180             :                 }
     181             : 
     182          10 :                 if (is_url(argv[i]) == EPKG_OK)
     183           0 :                         unlink(file);
     184             : 
     185             :         }
     186          10 :         pkg_manifest_keys_free(keys);
     187          10 :         pkgdb_release_lock(db, PKGDB_LOCK_EXCLUSIVE);
     188          10 :         pkgdb_close(db);
     189             :         
     190          10 :         if(failedpkgcount > 0) {
     191           2 :                 sbuf_finish(failedpkgs);
     192           2 :                 printf("\nFailed to install the following %d package(s): %s\n", failedpkgcount, sbuf_data(failedpkgs));
     193           2 :                 retcode = EPKG_FATAL;
     194             :         }
     195          10 :         sbuf_delete(failedpkgs);
     196             : 
     197          10 :         if (messages != NULL) {
     198           0 :                 sbuf_finish(messages);
     199           0 :                 printf("%s", sbuf_data(messages));
     200             :         }
     201             : 
     202          10 :         return (retcode == EPKG_OK ? EX_OK : EX_SOFTWARE);
     203             : }
     204             : 

Generated by: LCOV version 1.10