LCOV - code coverage report
Current view: top level - src - rquery.c (source / functions) Hit Total Coverage
Test: cov.info Lines: 0 118 0.0 %
Date: 2015-08-15 Functions: 0 3 0.0 %

          Line data    Source code
       1             : /*-
       2             :  * Copyright (c) 2011-2012 Baptiste Daroussin <bapt@FreeBSD.org>
       3             :  * Copyright (c) 2011-2012 Marin Atanasov Nikolov <dnaeon@gmail.com>
       4             :  * Copyright (c) 2012-2013 Bryan Drewery <bdrewery@FreeBSD.org>
       5             :  * Copyright (c) 2013-2014 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             : #include <sys/types.h>
      31             : #include <sys/sbuf.h>
      32             : 
      33             : #include <ctype.h>
      34             : #include <err.h>
      35             : #include <getopt.h>
      36             : #include <inttypes.h>
      37             : #include <pkg.h>
      38             : #include <stdio.h>
      39             : #include <stdlib.h>
      40             : #include <string.h>
      41             : #include <sysexits.h>
      42             : #include <unistd.h>
      43             : 
      44             : #include "pkgcli.h"
      45             : 
      46             : static struct query_flags accepted_rquery_flags[] = {
      47             :         { 'd', "nov",         1, PKG_LOAD_DEPS },
      48             :         { 'r', "nov",         1, PKG_LOAD_RDEPS },
      49             :         { 'C', "",            1, PKG_LOAD_CATEGORIES },
      50             :         { 'O', "kvdD",                1, PKG_LOAD_OPTIONS },
      51             :         { 'L', "",            1, PKG_LOAD_LICENSES },
      52             :         { 'B', "",            1, PKG_LOAD_SHLIBS_REQUIRED },
      53             :         { 'b', "",            1, PKG_LOAD_SHLIBS_PROVIDED },
      54             :         { 'A', "tv",          1, PKG_LOAD_ANNOTATIONS },
      55             :         { '?', "drCOLBbA",    1, PKG_LOAD_BASIC },    /* dbflags handled in analyse_query_string() */
      56             :         { '#', "drCOLBbA",    1, PKG_LOAD_BASIC },    /* dbflags handled in analyse_query_string() */
      57             :         { 's', "hb",          0, PKG_LOAD_BASIC },
      58             :         { 'n', "",            0, PKG_LOAD_BASIC },
      59             :         { 'e', "",            0, PKG_LOAD_BASIC },
      60             :         { 'v', "",            0, PKG_LOAD_BASIC },
      61             :         { 'o', "",            0, PKG_LOAD_BASIC },
      62             :         { 'R', "",            0, PKG_LOAD_BASIC },
      63             :         { 'p', "",            0, PKG_LOAD_BASIC },
      64             :         { 'm', "",            0, PKG_LOAD_BASIC },
      65             :         { 'c', "",            0, PKG_LOAD_BASIC },
      66             :         { 'w', "",            0, PKG_LOAD_BASIC },
      67             :         { 'l', "",            0, PKG_LOAD_BASIC },
      68             :         { 'q', "",            0, PKG_LOAD_BASIC },
      69             :         { 'M', "",            0, PKG_LOAD_BASIC }
      70             : };
      71             : 
      72             : void
      73           0 : usage_rquery(void)
      74             : {
      75           0 :         fprintf(stderr, "Usage: pkg rquery [-r reponame] [-I|<query-format>] <pkg-name>\n");
      76           0 :         fprintf(stderr, "       pkg rquery [-a] [-r reponame] [-I|<query-format>]\n");
      77           0 :         fprintf(stderr, "       pkg rquery -e <evaluation> [-r reponame] <query-format>\n");
      78           0 :         fprintf(stderr, "       pkg rquery [-Cgix] [-r reponame] [-I|<query-format>] <pattern> <...>\n\n");
      79           0 :         fprintf(stderr, "For more information see 'pkg help rquery.'\n");
      80           0 : }
      81             : 
      82             : static void
      83           0 : print_index(struct pkg *pkg, const char *portsdir)
      84             : {
      85             : 
      86           0 :         pkg_printf(
      87             :             "%n-%v|"                  /* PKGNAME */
      88             :             "%S/%o|"                  /* PORTDIR */
      89             :             "%p|"                     /* PREFIX */
      90             :             "%c|"                     /* COMMENT */
      91             :             "%S/%o/pkg-descr|"                /* _DESCR */
      92             :             "%m|"                     /* MAINTAINER */
      93             :             "%C%{%Cn%| %}|"           /* CATEGORIES */
      94             :             "|"                               /* BUILD_DEPENDS */
      95             :             "%d%{%dn-%dv%| %}|"               /* RUN_DEPENDS */
      96             :             "%w|"                     /* WWW */
      97             :             "|"                               /* EXTRACT_DEPENDS */
      98             :             "|"                               /* PATCH_DEPENDS */
      99             :             "\n",                     /* FETCH_DEPENDS */
     100             :             pkg, pkg, portsdir, pkg, pkg, pkg, portsdir, pkg, pkg, pkg, pkg,
     101             :             pkg);
     102           0 : }
     103             : 
     104             : int
     105           0 : exec_rquery(int argc, char **argv)
     106             : {
     107           0 :         struct pkgdb            *db = NULL;
     108           0 :         struct pkgdb_it         *it = NULL;
     109           0 :         struct pkg              *pkg = NULL;
     110           0 :         char                    *pkgname = NULL;
     111           0 :         int                      query_flags = PKG_LOAD_BASIC;
     112           0 :         match_t                  match = MATCH_EXACT;
     113             :         int                      ch;
     114           0 :         int                      ret = EPKG_OK;
     115           0 :         int                      retcode = EX_OK;
     116             :         int                      i;
     117           0 :         char                     multiline = 0;
     118           0 :         char                    *condition = NULL;
     119             :         const char              *portsdir;
     120           0 :         struct sbuf             *sqlcond = NULL;
     121           0 :         const unsigned int       q_flags_len = NELEM(accepted_rquery_flags);
     122           0 :         const char              *reponame = NULL;
     123             :         bool                     auto_update;
     124           0 :         bool                     onematched = false;
     125             :         bool                     old_quiet;
     126           0 :         bool                     index_output = false;
     127             : 
     128           0 :         struct option longopts[] = {
     129             :                 { "all",              no_argument,            NULL,   'a' },
     130             :                 { "case-sensitive",   no_argument,            NULL,   'C' },
     131             :                 { "evaluate",         required_argument,      NULL,   'e' },
     132             :                 { "glob",             no_argument,            NULL,   'g' },
     133             :                 { "case-insensitive", no_argument,            NULL,   'i' },
     134             :                 { "index-line",               no_argument,            NULL,   'I' },
     135             :                 { "repository",               required_argument,      NULL,   'r' },
     136             :                 { "no-repo-update",   no_argument,            NULL,   'U' },
     137             :                 { "regex",            no_argument,            NULL,   'x' },
     138             :                 { NULL,                 0,                      NULL,   0   },
     139             :         };
     140             : 
     141           0 :         portsdir = pkg_object_string(pkg_config_get("PORTSDIR"));
     142             : 
     143           0 :         while ((ch = getopt_long(argc, argv, "+aCgiIxe:r:U", longopts, NULL)) != -1) {
     144           0 :                 switch (ch) {
     145             :                 case 'a':
     146           0 :                         match = MATCH_ALL;
     147           0 :                         break;
     148             :                 case 'C':
     149           0 :                         pkgdb_set_case_sensitivity(true);
     150           0 :                         break;
     151             :                 case 'e':
     152           0 :                         match = MATCH_CONDITION;
     153           0 :                         condition = optarg;
     154           0 :                         break;
     155             :                 case 'g':
     156           0 :                         match = MATCH_GLOB;
     157           0 :                         break;
     158             :                 case 'i':
     159           0 :                         pkgdb_set_case_sensitivity(false);
     160           0 :                         break;
     161             :                 case 'I':
     162           0 :                         index_output = true;
     163           0 :                         break;
     164             :                 case 'r':
     165           0 :                         reponame = optarg;
     166           0 :                         break;
     167             :                 case 'U':
     168           0 :                         auto_update = false;
     169           0 :                         break;
     170             :                 case 'x':
     171           0 :                         match = MATCH_REGEX;
     172           0 :                         break;
     173             :                 default:
     174           0 :                         usage_rquery();
     175           0 :                         return (EX_USAGE);
     176             :                 }
     177             :         }
     178             : 
     179           0 :         argc -= optind;
     180           0 :         argv += optind;
     181             : 
     182           0 :         if (argc == 0 && !index_output) {
     183           0 :                 usage_rquery();
     184           0 :                 return (EX_USAGE);
     185             :         }
     186             : 
     187             :         /* Default to all packages if no pkg provided */
     188           0 :         if (!index_output) {
     189           0 :                 if (argc == 1 && condition == NULL && match == MATCH_EXACT) {
     190           0 :                         match = MATCH_ALL;
     191           0 :                 } else if (((argc == 1) ^ (match == MATCH_ALL )) && condition == NULL) {
     192           0 :                         usage_rquery();
     193           0 :                         return (EX_USAGE);
     194             :                 }
     195             :         } else {
     196           0 :                 if (argc == 0)
     197           0 :                         match = MATCH_ALL;
     198             :         }
     199             : 
     200           0 :         if (!index_output && analyse_query_string(argv[0], accepted_rquery_flags, q_flags_len, &query_flags, &multiline) != EPKG_OK)
     201           0 :                 return (EX_USAGE);
     202             : 
     203           0 :         if (condition != NULL) {
     204           0 :                 sqlcond = sbuf_new_auto();
     205           0 :                 if (format_sql_condition(condition, sqlcond, true) != EPKG_OK)
     206           0 :                         return (EX_USAGE);
     207           0 :                 sbuf_finish(sqlcond);
     208             :         }
     209             : 
     210           0 :         ret = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_REPO);
     211           0 :         if (ret == EPKG_ENOACCESS) {
     212           0 :                 warnx("Insufficient privileges to query the package database");
     213           0 :                 return (EX_NOPERM);
     214           0 :         } else if (ret != EPKG_OK)
     215           0 :                 return (EX_IOERR);
     216             : 
     217             :         /* first update the remote repositories if needed */
     218           0 :         old_quiet = quiet;
     219           0 :         quiet = true;
     220           0 :         if (auto_update && (ret = pkgcli_update(false, false, reponame)) != EPKG_OK)
     221           0 :                 return (ret);
     222           0 :         quiet = old_quiet;
     223             : 
     224           0 :         ret = pkgdb_open_all(&db, PKGDB_REMOTE, reponame);
     225           0 :         if (ret != EPKG_OK)
     226           0 :                 return (EX_IOERR);
     227             : 
     228           0 :         if (index_output)
     229           0 :                 query_flags = PKG_LOAD_BASIC|PKG_LOAD_CATEGORIES|PKG_LOAD_DEPS;
     230             : 
     231           0 :         if (match == MATCH_ALL || match == MATCH_CONDITION) {
     232           0 :                 const char *condition_sql = NULL;
     233           0 :                 if (match == MATCH_CONDITION && sqlcond)
     234           0 :                         condition_sql = sbuf_data(sqlcond);
     235           0 :                 if ((it = pkgdb_repo_query(db, condition_sql, match, reponame)) == NULL)
     236           0 :                         return (EX_IOERR);
     237             : 
     238           0 :                 while ((ret = pkgdb_it_next(it, &pkg, query_flags)) == EPKG_OK) {
     239           0 :                         if (index_output)
     240           0 :                                 print_index(pkg, portsdir);
     241             :                         else
     242           0 :                                 print_query(pkg, argv[0],  multiline);
     243             :                 }
     244             : 
     245           0 :                 if (ret != EPKG_END)
     246           0 :                         retcode = EX_SOFTWARE;
     247             : 
     248           0 :                 pkgdb_it_free(it);
     249             :         } else {
     250           0 :                 for (i = (index_output ? 0 : 1); i < argc; i++) {
     251           0 :                         pkgname = argv[i];
     252             : 
     253           0 :                         if ((it = pkgdb_repo_query(db, pkgname, match, reponame)) == NULL)
     254           0 :                                 return (EX_IOERR);
     255             : 
     256           0 :                         while ((ret = pkgdb_it_next(it, &pkg, query_flags)) == EPKG_OK) {
     257           0 :                                 onematched = true;
     258           0 :                                 if (index_output)
     259           0 :                                         print_index(pkg, portsdir);
     260             :                                 else
     261           0 :                                         print_query(pkg, argv[0], multiline);
     262             :                         }
     263             : 
     264           0 :                         if (ret != EPKG_END) {
     265           0 :                                 retcode = EX_SOFTWARE;
     266           0 :                                 break;
     267             :                         }
     268             : 
     269           0 :                         pkgdb_it_free(it);
     270             :                 }
     271           0 :                 if (!onematched && retcode == EX_OK)
     272           0 :                         retcode = EX_UNAVAILABLE;
     273             :         }
     274             : 
     275           0 :         pkg_free(pkg);
     276           0 :         pkgdb_close(db);
     277             : 
     278           0 :         return (retcode);
     279             : }

Generated by: LCOV version 1.10