├── .github └── workflows │ └── build-pkgin-tags.yml ├── .gitignore ├── CHANGES.md ├── CONTRIBUTORS ├── Doxyfile ├── Makefile.am ├── Makefile.in ├── README.md ├── REPOSITORIES ├── TODO ├── aclocal.m4 ├── actions.c ├── autoremove.c ├── cmd.h ├── compile ├── config.guess ├── config.h.in ├── config.sub ├── configure ├── configure.ac ├── depcomp ├── depends.c ├── download.c ├── external ├── automatic.c ├── dewey.c ├── dewey.h ├── fexec.c ├── humanize_number.c ├── humanize_number.h ├── iterate.c ├── lib.h ├── lpkg.c ├── opattern.c ├── pkgdb.c ├── plist.c ├── progressmeter.c ├── progressmeter.h ├── queue.h ├── var.c └── xwrapper.c ├── fsops.c ├── htdocs ├── gfx │ ├── pkgin-flashy-icon.png │ └── pkgin-icon-new.png ├── global.css └── index.html ├── impact.c ├── install-sh ├── main.c ├── messages.h ├── missing ├── mkpkgindb.sh ├── order.c ├── pkg_check.c ├── pkg_infos.c ├── pkg_install.c ├── pkg_str.c ├── pkgin.1.in ├── pkgin.h ├── pkgin.sql ├── pkgindb.c ├── pkgindb.h ├── pkgindb_queries.c ├── pkglist.c ├── preferred.c ├── preferred.conf ├── repositories.conf ├── selection.c ├── sqlite_callbacks.c ├── summary.c ├── tools.c └── tools.h /.github/workflows/build-pkgin-tags.yml: -------------------------------------------------------------------------------- 1 | name: Build all pkgin release tags 2 | on: 3 | workflow_dispatch: 4 | jobs: 5 | build-tags: 6 | runs-on: ubuntu-22.04 7 | steps: 8 | - name: Checkout repository 9 | uses: actions/checkout@v4 10 | with: 11 | fetch-depth: 0 12 | - name: Set up host 13 | run: | 14 | sudo apt-get update 15 | sudo apt-get install -y \ 16 | bmake \ 17 | build-essential \ 18 | cvs \ 19 | libarchive-dev \ 20 | libsqlite3-dev \ 21 | libssl-dev 22 | sudo mkdir -p /usr/local/{bin,sbin} 23 | mkdir ~/.ssh 24 | ssh-keyscan anoncvs.netbsd.org >>~/.ssh/known_hosts 25 | cvs -d anoncvs@anoncvs.netbsd.org:/cvsroot co -P \ 26 | pkgsrc/net/libfetch/files \ 27 | pkgsrc/pkgtools/libnbcompat/files \ 28 | pkgsrc/pkgtools/pkg_install/files \ 29 | pkgsrc/security/netpgpverify/files 30 | ( 31 | cd pkgsrc/pkgtools/libnbcompat/files 32 | ./configure --enable-db 33 | bmake 34 | ) 35 | CFLAGS="-DHAVE_NBCOMPAT_H=1" 36 | CFLAGS="${CFLAGS} -I${GITHUB_WORKSPACE}/pkgsrc/pkgtools/libnbcompat/files" 37 | export CFLAGS 38 | export SED="sed" 39 | ( 40 | cd pkgsrc/net/libfetch/files 41 | export BINOWN="$(id -un)" 42 | export ROOT_GROUP="$(id -gn)" 43 | export FETCH_WITH_INET6=yes 44 | bmake 45 | bmake DESTDIR=/tmp/destdir install 46 | ) 47 | ( 48 | cd pkgsrc/security/netpgpverify/files 49 | ./configure 50 | bmake 51 | bmake -f Makefile.lib.in 52 | ) 53 | ( 54 | cd pkgsrc/pkgtools/pkg_install/files 55 | sed -i -e '/optreset/d' admin/audit.c 56 | ln -s ${GITHUB_WORKSPACE}/pkgsrc/security/netpgpverify/files lib/netpgp 57 | cp ${GITHUB_WORKSPACE}/pkgsrc/security/netpgpverify/files/libnetpgpverify.a lib 58 | CFLAGS="${CFLAGS} -I${GITHUB_WORKSPACE}/pkgsrc/net/libfetch/files" 59 | CFLAGS="${CFLAGS} -I/tmp/destdir/usr/include" 60 | LDFLAGS="-L${GITHUB_WORKSPACE}/pkgsrc/pkgtools/libnbcompat/files" 61 | LDFLAGS="${LDFLAGS} -L/tmp/destdir/usr/lib" 62 | export PKGSRC_MACHINE_ARCH=x86_64 63 | export OPSYS=Linux 64 | export LDFLAGS 65 | export LIBS="-lnbcompat" 66 | ./configure --prefix=/usr/local 67 | bmake 68 | sudo bmake install 69 | ) 70 | - name: Build each tag 71 | run: | 72 | mkdir bin 73 | for tag in $(git tag | grep ^v); do 74 | # TODO: < v0.10 require patches for PKGIN_DBDIR / PKG_INSTALL_DIR 75 | case "${tag}" in 76 | v0.[0-9].*) 77 | continue 78 | ;; 79 | # TODO: some issues with the Makefile 80 | v0.*) 81 | continue 82 | ;; 83 | # TODO: pre-automake, do not support out-of-srcdir 84 | v20.*) 85 | continue 86 | ;; 87 | esac 88 | git checkout $tag 89 | mkdir build 90 | ( 91 | cd build 92 | CONFIGURE_ARGS="--prefix=/usr/local" 93 | case "${tag}" in 94 | v0.*) 95 | CONFIGURE_ARGS="${CONFIGURE_ARGS} --with-libraries=/tmp/destdir/usr/lib" 96 | CONFIGURE_ARGS="${CONFIGURE_ARGS} --with-includes=/tmp/destdir/usr/include" 97 | CONFIGURE_ARGS="${CONFIGURE_ARGS} --with-pkginstall=/usr/local/sbin" 98 | ;; 99 | *) 100 | CONFIGURE_ARGS="${CONFIGURE_ARGS} --disable-maintainer-mode" 101 | CONFIGURE_ARGS="${CONFIGURE_ARGS} --with-dbdir=/usr/local/.pkgdb" 102 | CONFIGURE_ARGS="${CONFIGURE_ARGS} --with-libarchive=/usr" 103 | CONFIGURE_ARGS="${CONFIGURE_ARGS} --with-libfetch=/tmp/destdir/usr" 104 | CONFIGURE_ARGS="${CONFIGURE_ARGS} --with-openssl=/usr" 105 | CONFIGURE_ARGS="${CONFIGURE_ARGS} --with-sqlite3=/usr" 106 | CONFIGURE_ARGS="${CONFIGURE_ARGS} --with-machine-arch=x86_64" 107 | CONFIGURE_ARGS="${CONFIGURE_ARGS} --with-pkg-install=/usr/local/sbin" 108 | ;; 109 | esac 110 | env \ 111 | CFLAGS="-DHAVE_NBCOMPAT_H=1 -I${GITHUB_WORKSPACE}/pkgsrc/pkgtools/libnbcompat/files" \ 112 | LDFLAGS="-L${GITHUB_WORKSPACE}/pkgsrc/pkgtools/libnbcompat/files" \ 113 | LIBS="-lnbcompat" \ 114 | ../configure ${CONFIGURE_ARGS} || (cat config.log && ./configure --help && false) 115 | bmake || make V=1 116 | ) 117 | sudo cp build/pkgin /usr/local/bin/pkgin-"$tag" 118 | rm -rf build 119 | done 120 | tar -czvf pkgin-bins.tar.gz /usr/local/{bin/pkgin-*,sbin/pkg*} 121 | - name: Upload artifacts 122 | uses: actions/upload-artifact@v4 123 | with: 124 | name: pkgin-binaries 125 | path: pkgin-bins.tar.gz 126 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | .deps 3 | Makefile 4 | autom4te.cache 5 | config.h 6 | config.h.in~ 7 | config.log 8 | config.status 9 | external/.deps 10 | external/.dirstamp 11 | pkgin 12 | pkgin.1 13 | pkgin.1.html 14 | pkgindb_create.h 15 | stamp-h1 16 | -------------------------------------------------------------------------------- /CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | Emile "iMil" Heitor - main developer 2 | Jonathan Perkin - primary maintainer 0.9.0 onwards 3 | Claude "zatmania" Charpentier - SQL 4 | Guillaume "GuiGui2" Lasmayous - tests and manpage 5 | Jeremy C. Reed - intensive tests and feedbacks 6 | Arnaud "stacktic" Ysmal - intensive tests + patches 7 | Antonio Huete "tuxillo" Jimenez - DragonFly port 8 | Min Sik Kim - Darwin port 9 | Filip Hajny - SunOS port 10 | Johannes Hofmann - bugfix 11 | Baptiste Daroussin - FreeBSD port + patches 12 | Gautam B.T. - MINIX port 13 | Thomas Adam - patches 14 | Sylvain "solevis" Mora - padawan 15 | Nicolas Thauvin - intensive tests + patches 16 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2020 Jonathan Perkin 3 | # 4 | # Permission to use, copy, modify, and distribute this software for any 5 | # purpose with or without fee is hereby granted, provided that the above 6 | # copyright notice and this permission notice appear in all copies. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | # 16 | 17 | bin_PROGRAMS= pkgin 18 | 19 | # 20 | # External source files imported from elsewhere. 21 | # 22 | openssh_SOURCES= external/progressmeter.c 23 | pkg_install_SOURCES= external/automatic.c external/dewey.c 24 | pkg_install_SOURCES+= external/fexec.c external/iterate.c external/lpkg.c 25 | pkg_install_SOURCES+= external/opattern.c external/pkgdb.c external/plist.c 26 | pkg_install_SOURCES+= external/var.c external/xwrapper.c 27 | 28 | pkgin_SOURCES= actions.c autoremove.c depends.c download.c fsops.c impact.c 29 | pkgin_SOURCES+= main.c order.c pkg_check.c pkg_infos.c pkg_install.c 30 | pkgin_SOURCES+= pkg_str.c pkgindb.c pkgindb_queries.c pkglist.c preferred.c 31 | pkgin_SOURCES+= selection.c sqlite_callbacks.c summary.c tools.c 32 | pkgin_SOURCES+= $(openssh_SOURCES) $(pkg_install_SOURCES) 33 | 34 | noinst_HEADERS= cmd.h messages.h pkgin.h pkgindb.h tools.h 35 | noinst_HEADERS+= external/dewey.h external/humanize_number.h external/lib.h 36 | noinst_HEADERS+= external/progressmeter.h external/queue.h 37 | 38 | # 39 | # Conditional sources. 40 | # 41 | if !HAVE_HUMANIZE_NUMBER 42 | pkgin_SOURCES+= external/humanize_number.c 43 | endif 44 | 45 | # 46 | # Required defines. 47 | # 48 | pkgin_CPPFLAGS= -DMACHINE_ARCH=\""$(MACHINE_ARCH)"\" 49 | pkgin_CPPFLAGS+= -DPKGIN_DBDIR=\""$(PKGIN_DBDIR)"\" 50 | pkgin_CPPFLAGS+= -DPKGIN_VERSION=\""$(VERSION)"\" 51 | pkgin_CPPFLAGS+= -DPKG_INSTALL_DIR=\""$(PKG_INSTALL_DIR)"\" 52 | pkgin_CPPFLAGS+= -DPKG_SYSCONFDIR=\""$(sysconfdir)"\" 53 | pkgin_CPPFLAGS+= -DPREFIX=\""$(prefix)"\" 54 | 55 | # 56 | # Manual pages. 57 | # 58 | man1_MANS= pkgin.1 59 | dist_pkgin_SOURCES= pkgin.1.in 60 | nodist_pkgin_SOURCES= pkgin.1 61 | pkgin.1: pkgin.1.in 62 | @sed -e 's,/var/db/pkgin,$(PKGIN_DBDIR),g' \ 63 | -e 's,/usr/pkg/etc,$(sysconfdir),g' $(srcdir)/pkgin.1.in >$@ 64 | 65 | # 66 | # Generated sources. 67 | # 68 | dist_pkgin_SOURCES+= pkgin.sql 69 | nodist_pkgin_SOURCES+= pkgindb_create.h 70 | pkgindb_create.h: Makefile pkgin.sql 71 | @echo "/* Automatically generated, DO NOT EDIT */" >$@ 72 | @echo "#define CREATE_DRYDB \" \\" >>$@ 73 | @sed -e 's/$$/ \\/' -e 's/\"/\\\"/g' $(srcdir)/pkgin.sql >>$@ 74 | @echo '"' >>$@ 75 | 76 | BUILT_SOURCES= $(nodist_pkgin_SOURCES) 77 | CLEANFILES= $(BUILT_SOURCES) 78 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | pkgin(1) -- A tool to manage pkgsrc binary packages. 2 | ==================================================== 3 | 4 | ## SYNOPSIS 5 | 6 | `pkgin` [`-dfFhpPvVyn`] [`-l` _limit_chars_] [`-c` _chroot_path_] [`-t` _log_file_] _command_ [package ...] 7 | 8 | ## DESCRIPTION 9 | 10 | The pkgin command is aimed at being an `apt` / `yum` like tool for managing pkgsrc(7) binary packages. It relies on pkg_summary(5) for installation, removal and upgrade of packages and associated dependencies, using a remote repository. 11 | 12 | ## OPTIONS 13 | 14 | The following command line arguments are supported: 15 | 16 | * `-c` chroot_path: 17 | Enable chrooting pkgin in the given repository 18 | 19 | * `-d`: 20 | Download only 21 | 22 | * `-f`: 23 | Force database update 24 | 25 | * `-F`: 26 | Force package reinstall 27 | 28 | * `-h`: 29 | Displays help for the command 30 | 31 | * `-l` _limit_chars_: 32 | Only include the packages with the specified [STATUS FLAGS][] 33 | 34 | * `-n`: 35 | Assumes "no" as default answer and print results of actions to be taken line per line 36 | 37 | * `-p`: 38 | Displays results in a parsable format 39 | 40 | * `-P`: 41 | Displays packages versions instead of globs (sd, sfd, srd) 42 | 43 | * `-t` log_file: 44 | Logs package browsing (dependencies and impact) to a given log file 45 | 46 | * `-v`: 47 | Displays pkgin version 48 | 49 | * `-V`: 50 | Be verbose when (un)installing 51 | 52 | * `-y`: 53 | Assumes "yes" as default answer, except for autoremove 54 | 55 | The `pkgin` utility provides several commands: 56 | 57 | * `autoremove`: 58 | Automatically removes orphan dependencies. When used with the `-n` flag, it can be used to show packages that are possibly not necessary. 59 | 60 | * `avail`: 61 | Lists all packages available in the repository. 62 | 63 | * `clean`: 64 | Delete downloaded packages from the cache directory. 65 | 66 | * `export`: 67 | Export the list of non-autoremovable packages to stdout (one category/package by line) 68 | 69 | * `upgrade`: 70 | Upgrade all packages to the newest versions available in the repository. 71 | 72 | * `import` _file_: 73 | Import a list of packages to be installed from file (one category/package by line) 74 | 75 | * `install` _package|glob_ ...: 76 | Performs installation or upgrade of package. If more than one packages are specified on the command-line, all will be installed (or upgraded). Instead of a package name, a glob can be specified in order to install specific versions. 77 | 78 | Example: 79 | 80 | pkgin in 'mysql-server>5.1<5.6' 81 | 82 | * `keep` _package_ ...: 83 | Marks package as "non auto-removable". A `keep`-able package is equivalent to a non-automatic package in pkgsrc(7) terminology. 84 | 85 | * `list`: 86 | Lists all packages installed locally on a system. If the l modifier is added to this command, show only packages matching the status flag. 87 | 88 | * `pkg-content` _package_: 89 | Show remote package content. 90 | 91 | * `pkg-descr` _package_: 92 | Show remote package long-description. 93 | 94 | * `pkg-build-defs` _package_: 95 | Show remote package build definitions. 96 | 97 | * `provides` _package_: 98 | Shows what a package provides to others 99 | 100 | * `remove` _package_ ...: 101 | Removes package as well as all packages depending on it. When more than one package are specified, they will all be uninstalled. By default, it will prompt you to confirm before package removals. 102 | 103 | * `requires` _package_: 104 | Shows what a package requires from others packages. 105 | 106 | * `search` _pattern_: 107 | Performs a regular expression search for a pattern in the repository. 108 | 109 | * `show-deps`: 110 | Displays all direct dependencies 111 | 112 | * `show-full-deps` _package_: 113 | Displays all direct dependencies recursively 114 | 115 | * `show-rev-deps` _package_: 116 | Displays all reverse direct dependencies for package. If more than one package is specified, pkgin will show recursively reverse direct dependencies for all packages on the command-line. 117 | 118 | * `show-category` _category_: 119 | Show packages belonging to category. 120 | 121 | * `show-pkg-category` _package_: 122 | Show package category. 123 | 124 | * `show-keep`: 125 | Display "non auto-removable" packages. 126 | 127 | * `show-no-keep`: 128 | Display "auto-removable" packages. 129 | 130 | * `unkeep` _package_ ...: 131 | Marks package as "auto-removable". If no other package depends on it, it will be removed when using the autoremove modifier. It is equivalent to an `automatic` package in pkgsrc(7) terminology. 132 | 133 | * `update`: 134 | Creates and populates the initial database of locally installed packages and available packages (from the remote pkg_summary(5) list). This is done automatically when pkgin is first used, when the system package database has been modified, or when pkgin is upgraded to a new database version. 135 | 136 | ## STATUS FLAGS 137 | 138 | When using the `-l` flag along with the list command, the following status flag must be set: 139 | 140 | * `=`: 141 | The installed version of the package is current. 142 | 143 | * `<`: 144 | The installed version of the package is older than the current version. 145 | 146 | * `>`: 147 | The installed version of the package is newer than the current version. 148 | 149 | ## ENVIRONMENT 150 | 151 | `PKG_REPOS` 152 | The `PKG_REPOS` environment variable can be pointed to a suitable repository or a list of space separated repositories in order to override _/usr/pkg/etc/pkgin/repositories.conf_ 153 | 154 | ## FILES 155 | 156 | * _/usr/pkg/etc/pkgin/repositories.conf_: 157 | This file contains a list of repository URIs that pkgin will use. It may contain macros `$arch` to define the machine hardware platform and `$osrelease` to define the release version for the operating system (as reported by uname(3)). 158 | 159 | * _/usr/pkg/etc/pkgin/preferred.conf_: 160 | This file contains a list of preferences regarding packages to be installed or upgraded. Each line defines a package preference taking the form of a simple glob(3). 161 | 162 | Example: 163 | 164 | mysql-server<5.6 165 | php>=5.4 166 | autoconf=2.69.* 167 | 168 | 169 | * _/var/db/pkgin_: 170 | This directory contains component needed by `pkgin` at run time. This directory can be completely emptied if `pkgin`'s database gets corrupted, `pkgin` will rebuild its database based on `pkg_install`'s `PKG_DB` next time it is called. 171 | 172 | * _/var/db/pkgin/cache_: 173 | This directory contains the packages downloaded by `pkgin`. It is safe to empty it regularily using `pkgin clean` or simply `rm -rf /var/db/pkgin/cache`. 174 | 175 | * _/var/db/pkgin/pkgin.db_: 176 | _pkgin.db_ is the main `pkgin` `SQLite` database. This format has been chosen in order to parse, query, match and order packages using the `SQL` language thus making packages list manipulation a lot easier. 177 | 178 | * _/var/db/pkgin/pkg_install-err.log_: 179 | This file contains errors and warnings given by pkg_add(1) and pkg_delete(1), which are the tools called by `pkgin` to manipulate packages themselves. 180 | 181 | * _/var/db/pkgin/sql.log_: 182 | This file contains `SQL` errors that might have occurred on a `SQLite` query. Mainly for debugging purposes. 183 | 184 | ## EXAMPLES 185 | 186 | Setup the initial database: 187 | 188 | # echo ftp://ftp.fr.netbsd.org/pub/pkgsrc/packages/NetBSD/i386/5.0/All > /usr/pkg/etc/pkgin/repositories.conf 189 | # pkgin update 190 | processing local summary... 191 | updating database: 100% 192 | downloading pkg_summary.bz2: 100% 193 | processing remote summary (ftp://ftp.fr.netbsd.org/pub/pkgsrc/packages/NetBSD/i386/5.0/All)... 194 | updating database: 100% 195 | 196 | Listing all packages available in the repository: 197 | 198 | # pkgin avail | more 199 | [...] 200 | autoconf-2.63 Generates automatic source code configuration scripts 201 | aumix-gtk-2.8nb3 Set mix levels (ncurses and GTK+ 2.0 interfaces) 202 | aumix-2.8nb7 Set mix levels (ncurses interface only) 203 | august-0.63b Simple Tk-based HTML editor 204 | audacity-1.2.6nb3 Audio editor 205 | [...] 206 | 207 | Install packages and their dependencies: 208 | 209 | # pkgin install links eterm 210 | nothing to upgrade. 211 | 11 packages to be installed: tiff-3.8.2nb4 png-1.2.35 libungif-4.1.4nb1 libltdl-1.5.26 jpeg-6bnb4 pcre-7.8 perl-5.10.0nb5 libast-0.6.1nb3 imlib2-1.4.2nb1 links-2.2nb1 eterm-0.9.4nb1 (25M to download, 64M to install) 212 | proceed ? [y/N] 213 | 214 | Remove packages and their reverse dependencies: 215 | 216 | # pkgin remove links eterm 217 | 2 packages to delete: links-2.2nb1 eterm-0.9.4nb1 218 | proceed ? [y/N] 219 | 220 | Remove orphan dependencies: 221 | 222 | # pkgin autoremove 223 | in order to remove packages from the autoremove list, flag those with the -k modifier. 224 | 9 packages to be autoremoved: libast-0.6.1nb3 pcre-7.8 imlib2-1.4.2nb1 tiff-3.8.2nb4 png-1.2.35 libungif-4.1.4nb1 libltdl-1.5.26 perl-5.10.0nb5 jpeg-6bnb4 225 | proceed ? [y/N] 226 | 227 | ## SEE ALSO 228 | 229 | pkg_add(1), pkg_info(1), pkg_summary(5), pkgsrc(7) 230 | 231 | ## AUTHORS 232 | 233 | * Emile `iMil` Heitor: 234 | Initial work and ongoing development. 235 | * Jonathan Perkin: 236 | Primary maintainer 0.9.0 onwards. 237 | 238 | ## CONTRIBUTORS 239 | 240 | * Jeremy C. Reed: 241 | Testing and refinements. 242 | * Arnaud Ysmal: 243 | Tests and patches 244 | * Claude Charpentier: 245 | SQLite schema, and SQL queries debugging. 246 | * Guillaume Lasmayous: 247 | Man page 248 | * Antonio Huete Jimenez: 249 | DragonFly port 250 | * Min Sik Kim: 251 | Darwin port 252 | * Filip Hajny: 253 | SunOS port 254 | * Baptiste Daroussin: 255 | FreeBSD port and patches 256 | * Gautam B.T.: 257 | MINIX port 258 | * Thomas `wiz` Klausner: 259 | Testing and refinements. 260 | * Youri `yrmt` Mouton: 261 | OSX testing and patches 262 | 263 | ## BUGS 264 | 265 | We're hunting them. 266 | -------------------------------------------------------------------------------- /REPOSITORIES: -------------------------------------------------------------------------------- 1 | # NetBSD OS release can look like 6.0_STABLE, do not use it as-is 2 | https://cdn.netbsd.org/pub/pkgsrc/packages/NetBSD/$arch/@OSREL@/All 3 | http://mirror-master.dragonflybsd.org/packages/$arch/DragonFly-$osrelease/stable/All/ 4 | ftp://ftp.minix3.org/pub/minix/packages/$osrelease/$arch/All 5 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | . Fix multi-repository (add REPOSITORY to Pkglist) 2 | . Add a flag to show only keep-packages whth pkgin ls 3 | -------------------------------------------------------------------------------- /autoremove.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2015 The NetBSD Foundation, Inc. 3 | * All rights reserved. 4 | * 5 | * This code is derived from software contributed to The NetBSD Foundation 6 | * by Emile "iMil" Heitor . 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 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 | * SUCH DAMAGE. 28 | */ 29 | 30 | /** 31 | * \file autoremove.c 32 | * 33 | * Cleanup orphan dependencies, keep and unkeep packages 34 | */ 35 | 36 | #include 37 | #include "pkgin.h" 38 | 39 | /* 40 | * Mostly duplicated from actions.c but modified as this needs to look at 41 | * p->lpkg. These should be merged if possible. 42 | */ 43 | static char ** 44 | get_sorted_list(Plisthead *pkgs) 45 | { 46 | Pkglist *p; 47 | size_t i = 0; 48 | char **names; 49 | 50 | /* Get number of entries for names allocation */ 51 | SLIST_FOREACH(p, pkgs, next) 52 | i++; 53 | 54 | names = xmalloc((i + 1) * sizeof(char *)); 55 | 56 | i = 0; 57 | SLIST_FOREACH(p, pkgs, next) { 58 | names[i++] = p->lpkg->full; 59 | } 60 | names[i] = NULL; 61 | 62 | qsort(names, i, sizeof(char *), sort_pkg_alpha); 63 | 64 | return names; 65 | } 66 | 67 | void 68 | pkgin_autoremove(void) 69 | { 70 | Plistarray *depshead; 71 | Plistnumbered *nokeephead, *keephead; 72 | Plisthead *removehead, *orderedhead; 73 | Pkglist *pkglist, *premove, *pdp, *p; 74 | char *toremove = NULL, **names, preserve[BUFSIZ]; 75 | int argn, is_keep_dep, removenb = 0; 76 | 77 | /* 78 | * Record all keep and no-keep packages. If either are empty then 79 | * we're done. 80 | */ 81 | if ((keephead = rec_pkglist(KEEP_LOCAL_PKGS)) == NULL) 82 | errx(EXIT_FAILURE, "no packages have been marked as keepable"); 83 | 84 | if ((nokeephead = rec_pkglist(NOKEEP_LOCAL_PKGS)) == NULL) { 85 | free_pkglist(&keephead->P_Plisthead); 86 | free(keephead); 87 | printf(MSG_ALL_KEEP_PKGS); 88 | return; 89 | } 90 | 91 | /* 92 | * Record all recursive dependencies for each keep package. This then 93 | * contains a list of all packages that are required. 94 | */ 95 | depshead = init_array(1); 96 | SLIST_FOREACH(p, keephead->P_Plisthead, next) { 97 | get_depends_recursive(p->full, depshead, DEPENDS_LOCAL); 98 | } 99 | 100 | removehead = init_head(); 101 | 102 | /* 103 | * For each non-keep package, get all of its reverse dependencies, and 104 | * if any of them are in keeplist then this package is still required. 105 | */ 106 | SLIST_FOREACH(pkglist, nokeephead->P_Plisthead, next) { 107 | is_keep_dep = 0; 108 | SLIST_FOREACH(pdp, &depshead->head[0], next) { 109 | if (strcmp(pdp->lpkg->full, pkglist->full) == 0) { 110 | is_keep_dep = 1; 111 | break; 112 | } 113 | } 114 | if (is_keep_dep) 115 | continue; 116 | 117 | /* 118 | * Also keep the package if it is a "preserve" package (one 119 | * that is specifically built to not be uninstalled, for 120 | * example important bootstrap packages. 121 | */ 122 | snprintf(preserve, BUFSIZ, "%s/%s/%s", pkgdb_get_dir(), 123 | pkglist->full, PRESERVE_FNAME); 124 | if (access(preserve, F_OK) != -1) 125 | continue; 126 | 127 | /* 128 | * Package can be auto removed, find its lpkg entry and add to 129 | * the list. 130 | */ 131 | premove = malloc_pkglist(); 132 | premove->action = ACTION_REMOVE; 133 | premove->lpkg = find_local_pkg(pkglist->full, pkglist->name); 134 | SLIST_INSERT_HEAD(removehead, premove, next); 135 | removenb++; 136 | } 137 | 138 | free_pkglist(&keephead->P_Plisthead); 139 | free(keephead); 140 | free_pkglist(&nokeephead->P_Plisthead); 141 | free(nokeephead); 142 | free_array(depshead); 143 | 144 | if (!removenb) { 145 | printf(MSG_NO_ORPHAN_DEPS); 146 | exit(EXIT_SUCCESS); 147 | } 148 | 149 | orderedhead = order_remove(removehead); 150 | free_pkglist(&removehead); 151 | 152 | if (SLIST_EMPTY(orderedhead)) { 153 | free_pkglist(&orderedhead); 154 | return; 155 | } 156 | 157 | names = get_sorted_list(orderedhead); 158 | for (argn = 0; names[argn] != NULL; argn++) { 159 | toremove = action_list(toremove, names[argn]); 160 | } 161 | free(names); 162 | 163 | printf(MSG_AUTOREMOVE_PKGS, removenb, toremove); 164 | if (!noflag) 165 | printf("\n"); 166 | 167 | if (check_yesno(DEFAULT_YES)) { 168 | do_pkg_remove(orderedhead); 169 | (void) update_db(LOCAL_SUMMARY, 1); 170 | } 171 | 172 | XFREE(toremove); 173 | free_pkglist(&orderedhead); 174 | } 175 | 176 | void 177 | show_pkg_keep(void) 178 | { 179 | Plistnumbered *plisthead; 180 | Pkglist *pkglist; 181 | 182 | plisthead = rec_pkglist(KEEP_LOCAL_PKGS); 183 | 184 | if (plisthead == NULL) { 185 | printf("%s\n", MSG_EMPTY_KEEP_LIST); 186 | return; 187 | } 188 | 189 | SLIST_FOREACH(pkglist, plisthead->P_Plisthead, next) 190 | printf("%-20s %s\n", pkglist->full, pkglist->comment); 191 | 192 | free_pkglist(&plisthead->P_Plisthead); 193 | free(plisthead); 194 | } 195 | 196 | void 197 | show_pkg_nokeep(void) 198 | { 199 | Plistnumbered *plisthead; 200 | Pkglist *pkglist; 201 | 202 | plisthead = rec_pkglist(NOKEEP_LOCAL_PKGS); 203 | 204 | if (plisthead == NULL) { 205 | printf("%s\n", MSG_EMPTY_NOKEEP_LIST); 206 | return; 207 | } 208 | 209 | SLIST_FOREACH(pkglist, plisthead->P_Plisthead, next) 210 | printf("%-20s %s\n", pkglist->full, pkglist->comment); 211 | 212 | free_pkglist(&plisthead->P_Plisthead); 213 | free(plisthead); 214 | } 215 | 216 | /* 217 | * Mark packages as keep (non-autoremovable) or nokeep (autoremovable). 218 | */ 219 | int 220 | pkg_keep(int type, char *pattern) 221 | { 222 | Pkglist *lpkg; 223 | char query[BUFSIZ]; 224 | 225 | if (!have_privs(PRIVS_PKGDB|PRIVS_PKGINDB)) 226 | errx(EXIT_FAILURE, MSG_DONT_HAVE_RIGHTS); 227 | 228 | if (is_empty_local_pkglist()) 229 | return 1; 230 | 231 | if ((lpkg = find_local_pkg(pattern, NULL)) == NULL) { 232 | printf(MSG_PKG_NOT_INSTALLED, pattern); 233 | return 1; 234 | } 235 | 236 | /* 237 | * Only print a message if the state is being changed, and update the 238 | * pkgdb as the source of truth. 239 | */ 240 | switch (type) { 241 | case KEEP: 242 | if (is_automatic_installed(lpkg->full)) { 243 | printf(MSG_MARKING_PKG_KEEP, lpkg->full); 244 | if (mark_as_automatic_installed(lpkg->full, 0) < 0) 245 | exit(EXIT_FAILURE); 246 | } 247 | sqlite3_snprintf(BUFSIZ, query, KEEP_PKG, lpkg->name); 248 | break; 249 | case UNKEEP: 250 | if (!is_automatic_installed(lpkg->full)) { 251 | printf(MSG_UNMARKING_PKG_KEEP, lpkg->full); 252 | if (mark_as_automatic_installed(lpkg->full, 1) < 0) 253 | exit(EXIT_FAILURE); 254 | } 255 | sqlite3_snprintf(BUFSIZ, query, UNKEEP_PKG, lpkg->name); 256 | break; 257 | } 258 | 259 | pkgindb_doquery(query, NULL, NULL); 260 | 261 | return 0; 262 | } 263 | -------------------------------------------------------------------------------- /cmd.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2015 The NetBSD Foundation, Inc. 3 | * All rights reserved. 4 | * 5 | * This code is derived from software contributed to The NetBSD Foundation 6 | * by Emile "iMil" Heitor . 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 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 | * SUCH DAMAGE. 28 | */ 29 | 30 | static struct command { 31 | const char *name; 32 | const char *shortcut; 33 | const char *descr; 34 | const int cmdtype; 35 | } cmd[] = { 36 | { "list", "ls", "List installed local packages", 37 | PKG_LLIST_CMD }, 38 | { "avail", "av", "List all available remote packages", 39 | PKG_RLIST_CMD }, 40 | { "search", "se", "Search for a remote package", 41 | PKG_SRCH_CMD }, 42 | { "install", "in", "Install or upgrade packages", 43 | PKG_INST_CMD }, 44 | { "update", "up" , "Refresh local and remote package lists", 45 | PKG_UPDT_CMD }, 46 | { "upgrade", "ug", "Upgrade all packages", 47 | PKG_UPGRD_CMD }, 48 | { "full-upgrade", "fug", "Upgrade all packages (deprecated)", 49 | PKG_FUPGRD_CMD }, 50 | { "remove", "rm", "Remove packages and any dependent packages", 51 | PKG_REMV_CMD }, 52 | { "keep", "ke", "Mark packages that should be kept", 53 | PKG_KEEP_CMD }, 54 | { "unkeep", "uk", "Mark packages that can be autoremoved", 55 | PKG_UNKEEP_CMD }, 56 | { "export", "ex", "Display PKGPATH for all keep packages", 57 | PKG_EXPORT_CMD }, 58 | { "import", "im", "Import keep package list from file", 59 | PKG_IMPORT_CMD }, 60 | { "show-keep", "sk", "Display keep packages", 61 | PKG_SHKP_CMD }, 62 | { "show-no-keep", "snk", "Display autoremovable packages", 63 | PKG_SHNOKP_CMD }, 64 | { "autoremove", "ar", "Remove orphaned dependencies", 65 | PKG_AUTORM_CMD }, 66 | { "clean", "cl", "Remove downloaded package files", 67 | PKG_CLEAN_CMD }, 68 | { "show-deps", "sd", "List remote package direct dependencies", 69 | PKG_SHDDP_CMD }, 70 | { "show-full-deps", "sfd", "List remote package full dependencies", 71 | PKG_SHFDP_CMD }, 72 | { "show-rev-deps", "srd", "List local package reverse dependencies", 73 | PKG_SHRDP_CMD }, 74 | { "provides", "prov", "Show which shared libraries a package provides", 75 | PKG_SHPROV_CMD }, 76 | { "requires", "req", "Show which shared libraries a package requires", 77 | PKG_SHREQ_CMD }, 78 | { "show-category", "sc", "List all packages belonging to a category", 79 | PKG_SHCAT_CMD }, 80 | { "show-pkg-category", "spc", "Show categories a package belongs to", 81 | PKG_SHPCAT_CMD }, 82 | { "show-all-categories", "sac", "List all known categories", 83 | PKG_SHALLCAT_CMD }, 84 | { "pkg-content", "pc", "Show remote package content", 85 | PKG_SHPKGCONT_CMD }, 86 | { "pkg-descr", "pd", "Show remote package long-description", 87 | PKG_SHPKGDESC_CMD }, 88 | { "pkg-build-defs", "pbd", "Show remote package build definitions", 89 | PKG_SHPKGBDEFS_CMD }, 90 | { "tonic", "to", "Gin Tonic recipe", 91 | PKG_GINTO_CMD }, 92 | { "stats", "st", "Show local and remote package statistics", 93 | PKG_STATS_CMD }, 94 | { NULL, NULL, NULL, 0 } 95 | }; 96 | -------------------------------------------------------------------------------- /compile: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # Wrapper for compilers which do not understand '-c -o'. 3 | 4 | scriptversion=2018-03-07.03; # UTC 5 | 6 | # Copyright (C) 1999-2021 Free Software Foundation, Inc. 7 | # Written by Tom Tromey . 8 | # 9 | # This program is free software; you can redistribute it and/or modify 10 | # it under the terms of the GNU General Public License as published by 11 | # the Free Software Foundation; either version 2, or (at your option) 12 | # any later version. 13 | # 14 | # This program is distributed in the hope that it will be useful, 15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | # GNU General Public License for more details. 18 | # 19 | # You should have received a copy of the GNU General Public License 20 | # along with this program. If not, see . 21 | 22 | # As a special exception to the GNU General Public License, if you 23 | # distribute this file as part of a program that contains a 24 | # configuration script generated by Autoconf, you may include it under 25 | # the same distribution terms that you use for the rest of that program. 26 | 27 | # This file is maintained in Automake, please report 28 | # bugs to or send patches to 29 | # . 30 | 31 | nl=' 32 | ' 33 | 34 | # We need space, tab and new line, in precisely that order. Quoting is 35 | # there to prevent tools from complaining about whitespace usage. 36 | IFS=" "" $nl" 37 | 38 | file_conv= 39 | 40 | # func_file_conv build_file lazy 41 | # Convert a $build file to $host form and store it in $file 42 | # Currently only supports Windows hosts. If the determined conversion 43 | # type is listed in (the comma separated) LAZY, no conversion will 44 | # take place. 45 | func_file_conv () 46 | { 47 | file=$1 48 | case $file in 49 | / | /[!/]*) # absolute file, and not a UNC file 50 | if test -z "$file_conv"; then 51 | # lazily determine how to convert abs files 52 | case `uname -s` in 53 | MINGW*) 54 | file_conv=mingw 55 | ;; 56 | CYGWIN* | MSYS*) 57 | file_conv=cygwin 58 | ;; 59 | *) 60 | file_conv=wine 61 | ;; 62 | esac 63 | fi 64 | case $file_conv/,$2, in 65 | *,$file_conv,*) 66 | ;; 67 | mingw/*) 68 | file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` 69 | ;; 70 | cygwin/* | msys/*) 71 | file=`cygpath -m "$file" || echo "$file"` 72 | ;; 73 | wine/*) 74 | file=`winepath -w "$file" || echo "$file"` 75 | ;; 76 | esac 77 | ;; 78 | esac 79 | } 80 | 81 | # func_cl_dashL linkdir 82 | # Make cl look for libraries in LINKDIR 83 | func_cl_dashL () 84 | { 85 | func_file_conv "$1" 86 | if test -z "$lib_path"; then 87 | lib_path=$file 88 | else 89 | lib_path="$lib_path;$file" 90 | fi 91 | linker_opts="$linker_opts -LIBPATH:$file" 92 | } 93 | 94 | # func_cl_dashl library 95 | # Do a library search-path lookup for cl 96 | func_cl_dashl () 97 | { 98 | lib=$1 99 | found=no 100 | save_IFS=$IFS 101 | IFS=';' 102 | for dir in $lib_path $LIB 103 | do 104 | IFS=$save_IFS 105 | if $shared && test -f "$dir/$lib.dll.lib"; then 106 | found=yes 107 | lib=$dir/$lib.dll.lib 108 | break 109 | fi 110 | if test -f "$dir/$lib.lib"; then 111 | found=yes 112 | lib=$dir/$lib.lib 113 | break 114 | fi 115 | if test -f "$dir/lib$lib.a"; then 116 | found=yes 117 | lib=$dir/lib$lib.a 118 | break 119 | fi 120 | done 121 | IFS=$save_IFS 122 | 123 | if test "$found" != yes; then 124 | lib=$lib.lib 125 | fi 126 | } 127 | 128 | # func_cl_wrapper cl arg... 129 | # Adjust compile command to suit cl 130 | func_cl_wrapper () 131 | { 132 | # Assume a capable shell 133 | lib_path= 134 | shared=: 135 | linker_opts= 136 | for arg 137 | do 138 | if test -n "$eat"; then 139 | eat= 140 | else 141 | case $1 in 142 | -o) 143 | # configure might choose to run compile as 'compile cc -o foo foo.c'. 144 | eat=1 145 | case $2 in 146 | *.o | *.[oO][bB][jJ]) 147 | func_file_conv "$2" 148 | set x "$@" -Fo"$file" 149 | shift 150 | ;; 151 | *) 152 | func_file_conv "$2" 153 | set x "$@" -Fe"$file" 154 | shift 155 | ;; 156 | esac 157 | ;; 158 | -I) 159 | eat=1 160 | func_file_conv "$2" mingw 161 | set x "$@" -I"$file" 162 | shift 163 | ;; 164 | -I*) 165 | func_file_conv "${1#-I}" mingw 166 | set x "$@" -I"$file" 167 | shift 168 | ;; 169 | -l) 170 | eat=1 171 | func_cl_dashl "$2" 172 | set x "$@" "$lib" 173 | shift 174 | ;; 175 | -l*) 176 | func_cl_dashl "${1#-l}" 177 | set x "$@" "$lib" 178 | shift 179 | ;; 180 | -L) 181 | eat=1 182 | func_cl_dashL "$2" 183 | ;; 184 | -L*) 185 | func_cl_dashL "${1#-L}" 186 | ;; 187 | -static) 188 | shared=false 189 | ;; 190 | -Wl,*) 191 | arg=${1#-Wl,} 192 | save_ifs="$IFS"; IFS=',' 193 | for flag in $arg; do 194 | IFS="$save_ifs" 195 | linker_opts="$linker_opts $flag" 196 | done 197 | IFS="$save_ifs" 198 | ;; 199 | -Xlinker) 200 | eat=1 201 | linker_opts="$linker_opts $2" 202 | ;; 203 | -*) 204 | set x "$@" "$1" 205 | shift 206 | ;; 207 | *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) 208 | func_file_conv "$1" 209 | set x "$@" -Tp"$file" 210 | shift 211 | ;; 212 | *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) 213 | func_file_conv "$1" mingw 214 | set x "$@" "$file" 215 | shift 216 | ;; 217 | *) 218 | set x "$@" "$1" 219 | shift 220 | ;; 221 | esac 222 | fi 223 | shift 224 | done 225 | if test -n "$linker_opts"; then 226 | linker_opts="-link$linker_opts" 227 | fi 228 | exec "$@" $linker_opts 229 | exit 1 230 | } 231 | 232 | eat= 233 | 234 | case $1 in 235 | '') 236 | echo "$0: No command. Try '$0 --help' for more information." 1>&2 237 | exit 1; 238 | ;; 239 | -h | --h*) 240 | cat <<\EOF 241 | Usage: compile [--help] [--version] PROGRAM [ARGS] 242 | 243 | Wrapper for compilers which do not understand '-c -o'. 244 | Remove '-o dest.o' from ARGS, run PROGRAM with the remaining 245 | arguments, and rename the output as expected. 246 | 247 | If you are trying to build a whole package this is not the 248 | right script to run: please start by reading the file 'INSTALL'. 249 | 250 | Report bugs to . 251 | EOF 252 | exit $? 253 | ;; 254 | -v | --v*) 255 | echo "compile $scriptversion" 256 | exit $? 257 | ;; 258 | cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \ 259 | icl | *[/\\]icl | icl.exe | *[/\\]icl.exe ) 260 | func_cl_wrapper "$@" # Doesn't return... 261 | ;; 262 | esac 263 | 264 | ofile= 265 | cfile= 266 | 267 | for arg 268 | do 269 | if test -n "$eat"; then 270 | eat= 271 | else 272 | case $1 in 273 | -o) 274 | # configure might choose to run compile as 'compile cc -o foo foo.c'. 275 | # So we strip '-o arg' only if arg is an object. 276 | eat=1 277 | case $2 in 278 | *.o | *.obj) 279 | ofile=$2 280 | ;; 281 | *) 282 | set x "$@" -o "$2" 283 | shift 284 | ;; 285 | esac 286 | ;; 287 | *.c) 288 | cfile=$1 289 | set x "$@" "$1" 290 | shift 291 | ;; 292 | *) 293 | set x "$@" "$1" 294 | shift 295 | ;; 296 | esac 297 | fi 298 | shift 299 | done 300 | 301 | if test -z "$ofile" || test -z "$cfile"; then 302 | # If no '-o' option was seen then we might have been invoked from a 303 | # pattern rule where we don't need one. That is ok -- this is a 304 | # normal compilation that the losing compiler can handle. If no 305 | # '.c' file was seen then we are probably linking. That is also 306 | # ok. 307 | exec "$@" 308 | fi 309 | 310 | # Name of file we expect compiler to create. 311 | cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` 312 | 313 | # Create the lock directory. 314 | # Note: use '[/\\:.-]' here to ensure that we don't use the same name 315 | # that we are using for the .o file. Also, base the name on the expected 316 | # object file name, since that is what matters with a parallel build. 317 | lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d 318 | while true; do 319 | if mkdir "$lockdir" >/dev/null 2>&1; then 320 | break 321 | fi 322 | sleep 1 323 | done 324 | # FIXME: race condition here if user kills between mkdir and trap. 325 | trap "rmdir '$lockdir'; exit 1" 1 2 15 326 | 327 | # Run the compile. 328 | "$@" 329 | ret=$? 330 | 331 | if test -f "$cofile"; then 332 | test "$cofile" = "$ofile" || mv "$cofile" "$ofile" 333 | elif test -f "${cofile}bj"; then 334 | test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" 335 | fi 336 | 337 | rmdir "$lockdir" 338 | exit $ret 339 | 340 | # Local Variables: 341 | # mode: shell-script 342 | # sh-indentation: 2 343 | # eval: (add-hook 'before-save-hook 'time-stamp) 344 | # time-stamp-start: "scriptversion=" 345 | # time-stamp-format: "%:y-%02m-%02d.%02H" 346 | # time-stamp-time-zone: "UTC0" 347 | # time-stamp-end: "; # UTC" 348 | # End: 349 | -------------------------------------------------------------------------------- /config.h.in: -------------------------------------------------------------------------------- 1 | /* config.h.in. Generated from configure.ac by autoheader. */ 2 | 3 | /* Define to 1 if you have the header file. */ 4 | #undef HAVE_BSD_LIBUTIL_H 5 | 6 | /* Define to 1 if you have the header file. */ 7 | #undef HAVE_INTTYPES_H 8 | 9 | /* Define to 1 if you have the 'archive' library (-larchive). */ 10 | #undef HAVE_LIBARCHIVE 11 | 12 | /* Define to 1 if you have the 'fetch' library (-lfetch). */ 13 | #undef HAVE_LIBFETCH 14 | 15 | /* Define to 1 if you have the 'sqlite3' library (-lsqlite3). */ 16 | #undef HAVE_LIBSQLITE3 17 | 18 | /* Define to 1 if you have the header file. */ 19 | #undef HAVE_LIBUTIL_H 20 | 21 | /* Define to 1 if you have the header file. */ 22 | #undef HAVE_STDINT_H 23 | 24 | /* Define to 1 if you have the header file. */ 25 | #undef HAVE_STDIO_H 26 | 27 | /* Define to 1 if you have the header file. */ 28 | #undef HAVE_STDLIB_H 29 | 30 | /* Define to 1 if you have the header file. */ 31 | #undef HAVE_STRINGS_H 32 | 33 | /* Define to 1 if you have the header file. */ 34 | #undef HAVE_STRING_H 35 | 36 | /* Define to 1 if 'st_mtimespec.tv_nsec' is a member of 'struct stat'. */ 37 | #undef HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC 38 | 39 | /* Define to 1 if 'st_mtime_n' is a member of 'struct stat'. */ 40 | #undef HAVE_STRUCT_STAT_ST_MTIME_N 41 | 42 | /* Define to 1 if 'st_mtime_usec' is a member of 'struct stat'. */ 43 | #undef HAVE_STRUCT_STAT_ST_MTIME_USEC 44 | 45 | /* Define to 1 if 'st_mtim.tv_nsec' is a member of 'struct stat'. */ 46 | #undef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC 47 | 48 | /* Define to 1 if 'st_umtime' is a member of 'struct stat'. */ 49 | #undef HAVE_STRUCT_STAT_ST_UMTIME 50 | 51 | /* Define to 1 if you have the header file. */ 52 | #undef HAVE_SYS_STAT_H 53 | 54 | /* Define to 1 if you have the header file. */ 55 | #undef HAVE_SYS_TERMIOS_H 56 | 57 | /* Define to 1 if you have the header file. */ 58 | #undef HAVE_SYS_TYPES_H 59 | 60 | /* Define to 1 if you have the header file. */ 61 | #undef HAVE_TERMIOS_H 62 | 63 | /* Define to 1 if you have the header file. */ 64 | #undef HAVE_UNISTD_H 65 | 66 | /* Define to 1 if you have the header file. */ 67 | #undef HAVE_UTIL_H 68 | 69 | /* Name of package */ 70 | #undef PACKAGE 71 | 72 | /* Define to the address where bug reports for this package should be sent. */ 73 | #undef PACKAGE_BUGREPORT 74 | 75 | /* Define to the full name of this package. */ 76 | #undef PACKAGE_NAME 77 | 78 | /* Define to the full name and version of this package. */ 79 | #undef PACKAGE_STRING 80 | 81 | /* Define to the one symbol short name of this package. */ 82 | #undef PACKAGE_TARNAME 83 | 84 | /* Define to the home page for this package. */ 85 | #undef PACKAGE_URL 86 | 87 | /* Define to the version of this package. */ 88 | #undef PACKAGE_VERSION 89 | 90 | /* Define to 1 if all of the C89 standard headers exist (not just the ones 91 | required in a freestanding environment). This macro is provided for 92 | backward compatibility; new code need not use it. */ 93 | #undef STDC_HEADERS 94 | 95 | /* Version number of package */ 96 | #undef VERSION 97 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | AC_PREREQ([2.61]) 2 | AC_INIT([pkgin], [25.5.2], [https://github.com/NetBSDfr/pkgin/issues]) 3 | AC_CONFIG_SRCDIR([actions.c]) 4 | AC_CONFIG_HEADERS([config.h]) 5 | 6 | AM_INIT_AUTOMAKE([foreign subdir-objects]) 7 | AM_MAINTAINER_MODE([enable]) 8 | AM_SILENT_RULES([yes]) 9 | 10 | # Code is written to a C99 baseline. 11 | : ${CFLAGS="-std=c99 -g -O2"} 12 | 13 | # Checks for programs. 14 | AC_PROG_CC 15 | AC_PROG_INSTALL 16 | 17 | # 18 | # Enable some useful compiler warnings if running in maintainer mode. Note 19 | # that maintainer mode is explicitly disabled in the pkgsrc build to avoid 20 | # user failures (the bug reports are nice, the user experience is not). 21 | # 22 | AS_IF([test "x$USE_MAINTAINER_MODE" = "xyes"], 23 | CFLAGS="$CFLAGS -Werror -Wall -Wextra -Wunused -Wno-unused-parameter" 24 | ) 25 | 26 | # 27 | # --with-dbdir=/path/to/pkgin/db 28 | # 29 | AC_ARG_WITH([dbdir], 30 | [AS_HELP_STRING([--with-dbdir=DIR], 31 | [Path to pkgin database directory])], 32 | [PKGIN_DBDIR="$withval"], 33 | [AC_MSG_ERROR([--with-dbdir is mandatory])] 34 | ) 35 | AC_SUBST(PKGIN_DBDIR) 36 | 37 | # 38 | # Check for required libraries. All of them accept --with-*=DIR arguments 39 | # so that we can be specific about which one to use. 40 | # 41 | AC_ARG_WITH([libarchive], 42 | [AS_HELP_STRING([--with-libarchive=DIR], 43 | [Root libarchive directory (e.g. /usr/local)])], 44 | [CPPFLAGS="$CPPFLAGS -I$withval/include" 45 | LDFLAGS="$LDFLAGS -L$withval/lib"] 46 | ) 47 | AC_CHECK_HEADER([archive.h],[],[AC_MSG_FAILURE([can't find archive.h])]) 48 | AC_CHECK_LIB([archive],[archive_read_new],[], 49 | [AC_MSG_FAILURE([can't find libarchive])] 50 | ) 51 | 52 | AC_ARG_WITH([libfetch], 53 | [AS_HELP_STRING([--with-libfetch=DIR], 54 | [Root libfetch directory (e.g. /usr/local)])], 55 | [CPPFLAGS="$CPPFLAGS -I$withval/include" 56 | LDFLAGS="$LDFLAGS -L$withval/lib"] 57 | ) 58 | AC_CHECK_HEADER([fetch.h],[],[AC_MSG_FAILURE([can't find fetch.h])]) 59 | AC_CHECK_LIB([fetch],[fetchMakeURL],[], 60 | [AC_MSG_FAILURE([can't find libfetch])] 61 | ) 62 | 63 | AC_ARG_WITH([sqlite3], 64 | [AS_HELP_STRING([--with-sqlite3=DIR], 65 | [Root sqlite3 directory (e.g. /usr/local)])], 66 | [CPPFLAGS="$CPPFLAGS -I$withval/include" 67 | LDFLAGS="$LDFLAGS -L$withval/lib"] 68 | ) 69 | AC_CHECK_HEADER([sqlite3.h],[],[AC_MSG_FAILURE([can't find sqlite3.h])]) 70 | AC_CHECK_LIB([sqlite3],[sqlite3_open_v2],[], 71 | [AC_MSG_FAILURE([can't find libsqlite3])] 72 | ) 73 | 74 | # 75 | # --with-machine-arch=MACHINE_ARCH 76 | # 77 | AC_ARG_WITH([machine-arch], 78 | [AS_HELP_STRING([--with-machine-arch=ARCH], 79 | [Target MACHINE_ARCH])], 80 | [MACHINE_ARCH="$withval"], 81 | [AC_MSG_ERROR([--with-machine-arch is mandatory])] 82 | ) 83 | AC_SUBST(MACHINE_ARCH) 84 | 85 | # 86 | # --with-pkg-install=/path/to/pkg_install/sbin 87 | # 88 | AC_ARG_WITH([pkg-install], 89 | [AS_HELP_STRING([--with-pkg-install=DIR], 90 | [Path to pkg_install commands (e.g. /usr/pkg/sbin)])], 91 | [PKG_INSTALL_DIR="$withval"], 92 | [AC_MSG_ERROR([--with-pkg-install is mandatory])] 93 | ) 94 | AC_SUBST(PKG_INSTALL_DIR) 95 | 96 | # 97 | # There is no real merit in testing for lots of different library functions and 98 | # headers if they're essential anyway. It's unlikely we will want to support 99 | # esoteric environments. 100 | # 101 | # The only functions we test for are those that are non-portable, and for which 102 | # we provide compat functions for environments where they are not available. 103 | # 104 | AC_CHECK_FUNC([humanize_number], 105 | AM_CONDITIONAL([HAVE_HUMANIZE_NUMBER], true), 106 | # May also be in libutil 107 | [AC_SEARCH_LIBS([humanize_number], [util], 108 | AM_CONDITIONAL(HAVE_HUMANIZE_NUMBER, true), 109 | AM_CONDITIONAL(HAVE_HUMANIZE_NUMBER, false) 110 | )] 111 | ) 112 | AC_CHECK_HEADERS([util.h bsd/libutil.h libutil.h]) 113 | AC_CHECK_HEADERS([sys/termios.h termios.h]) 114 | # 115 | # Tests for library functions that may exist outside of libc. 116 | # 117 | AC_SEARCH_LIBS([socket], [socket]) 118 | AC_SEARCH_LIBS([inet_addr], [nsl]) 119 | 120 | # 121 | # Check for high-resolution timestamps in struct stat (from libarchive). 122 | # 123 | AC_CHECK_MEMBERS([struct stat.st_mtimespec.tv_nsec]) 124 | AC_CHECK_MEMBERS([struct stat.st_mtim.tv_nsec]) 125 | AC_CHECK_MEMBERS([struct stat.st_mtime_n]) # AIX 126 | AC_CHECK_MEMBERS([struct stat.st_umtime]) # Tru64 127 | AC_CHECK_MEMBERS([struct stat.st_mtime_usec]) # Hurd 128 | 129 | AC_CONFIG_FILES([Makefile]) 130 | AC_OUTPUT 131 | -------------------------------------------------------------------------------- /download.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2015 The NetBSD Foundation, Inc. 3 | * All rights reserved. 4 | * 5 | * This code is derived from software contributed to The NetBSD Foundation 6 | * by Emile "iMil" Heitor . 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 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 | * SUCH DAMAGE. 28 | */ 29 | 30 | #include "pkgin.h" 31 | #include "external/progressmeter.h" 32 | 33 | extern char fetchflags[3]; 34 | 35 | /* 36 | * Open a pkg_summary and if newer than local return an open libfetch 37 | * connection to it. 38 | */ 39 | Sumfile * 40 | sum_open(char *str_url, time_t *db_mtime) 41 | { 42 | Sumfile *sum = NULL; 43 | fetchIO *f = NULL; 44 | struct url *url; 45 | struct url_stat st; 46 | 47 | url = fetchParseURL(str_url); 48 | 49 | if (url == NULL || (f = fetchXGet(url, &st, fetchflags)) == NULL) 50 | goto nofetch; 51 | 52 | if (st.size == -1) { /* could not obtain file size */ 53 | *db_mtime = 0; /* not -1, don't force update */ 54 | goto nofetch; 55 | } 56 | 57 | if (st.mtime <= *db_mtime) { 58 | /* 59 | * -1 used to identify return type, 60 | * local summary up-to-date 61 | */ 62 | *db_mtime = -1; 63 | goto nofetch; 64 | } 65 | 66 | *db_mtime = st.mtime; 67 | 68 | /* st.size is an off_t, it will be > SSIZE_MAX on 32 bits systems */ 69 | if (sizeof(st.size) == sizeof(SSIZE_MAX) && st.size > SSIZE_MAX - 1) 70 | err(EXIT_FAILURE, "file is too large"); 71 | 72 | sum = xmalloc(sizeof(Sumfile)); 73 | 74 | sum->fd = f; 75 | sum->url = url; 76 | sum->size = st.size; 77 | sum->pos = 0; 78 | goto out; 79 | nofetch: 80 | if (url) 81 | fetchFreeURL(url); 82 | if (f) 83 | fetchIO_close(f); 84 | out: 85 | return sum; 86 | } 87 | 88 | /* 89 | * archive_read_open open callback. As we already have an open 90 | * libfetch handler all we need to do is print the download messages. 91 | */ 92 | int 93 | sum_start(struct archive *a, void *data) 94 | { 95 | Sumfile *sum = data; 96 | char *p; 97 | 98 | if ((p = strrchr(sum->url->doc, '/')) != NULL) 99 | p++; 100 | else 101 | p = (char *)sum->url->doc; /* should not happen */ 102 | 103 | if (parsable) 104 | printf("downloading %s", p); 105 | else { 106 | printf("downloading %s: 0%%", p); 107 | fflush(stdout); 108 | start_progress_meter(p, sum->size, &sum->pos); 109 | } 110 | 111 | return ARCHIVE_OK; 112 | } 113 | 114 | /* 115 | * archive_read_open read callback. Read the next chunk of data from libfetch 116 | * and update the read position for the progress meter. 117 | */ 118 | ssize_t 119 | sum_read(struct archive *a, void *data, const void **buf) 120 | { 121 | Sumfile *sum = data; 122 | ssize_t fetched; 123 | 124 | *buf = sum->buf; 125 | 126 | fetched = fetchIO_read(sum->fd, sum->buf, sizeof(sum->buf)); 127 | 128 | if (fetched == -1) 129 | errx(EXIT_FAILURE, "failure during fetch of file: %s", 130 | fetchLastErrString); 131 | 132 | sum->pos += fetched; 133 | 134 | return fetched; 135 | } 136 | 137 | /* 138 | * archive_read_open close callback. Stop the progress meter and close the 139 | * libfetch handler. 140 | */ 141 | int 142 | sum_close(struct archive *a, void *data) 143 | { 144 | Sumfile *sum = data; 145 | 146 | if (parsable) 147 | printf(" done.\n"); 148 | else 149 | stop_progress_meter(); 150 | 151 | fetchIO_close(sum->fd); 152 | fetchFreeURL(sum->url); 153 | XFREE(sum); 154 | 155 | return ARCHIVE_OK; 156 | } 157 | 158 | /* 159 | * Download a package to the local cache. 160 | */ 161 | off_t 162 | download_pkg(char *pkg_url, FILE *fp, int cur, int total) 163 | { 164 | struct url_stat st; 165 | size_t size, wrote; 166 | ssize_t fetched; 167 | off_t statsize = 0, written = 0; 168 | struct url *url; 169 | fetchIO *f = NULL; 170 | char buf[4096]; 171 | char *pkg, *ptr, *msg = NULL; 172 | 173 | if ((url = fetchParseURL(pkg_url)) == NULL) 174 | errx(EXIT_FAILURE, "%s: parse failure", pkg_url); 175 | 176 | if ((f = fetchXGet(url, &st, fetchflags)) == NULL) { 177 | fprintf(stderr, "download error: %s %s\n", pkg_url, 178 | fetchLastErrString); 179 | fetchFreeURL(url); 180 | return -1; 181 | } 182 | fetchFreeURL(url); 183 | 184 | if ((pkg = strrchr(pkg_url, '/')) != NULL) 185 | pkg++; 186 | else 187 | pkg = (char *)pkg_url; /* should not happen */ 188 | 189 | if (parsable) { 190 | printf("[%d/%d] downloading %s", cur, total, pkg); 191 | } else { 192 | msg = xasprintf("[%d/%d] %s", cur, total, pkg); 193 | fflush(stdout); 194 | start_progress_meter(msg, st.size, &statsize); 195 | } 196 | 197 | while (written < st.size) { 198 | if ((fetched = fetchIO_read(f, buf, sizeof(buf))) == 0) 199 | break; 200 | if (fetched < 0 && errno == EINTR) 201 | continue; 202 | if (fetched < 0) { 203 | fprintf(stderr, "download error: %s", 204 | fetchLastErrString); 205 | return -1; 206 | } 207 | 208 | statsize += fetched; 209 | size = (size_t)fetched; 210 | 211 | for (ptr = buf; size > 0; ptr += wrote, size -= wrote) { 212 | if ((wrote = fwrite(ptr, 1, size, fp)) < size) { 213 | if (ferror(fp) && errno == EINTR) 214 | clearerr(fp); 215 | else 216 | break; 217 | } 218 | written += (off_t)wrote; 219 | } 220 | } 221 | 222 | if (parsable) 223 | printf(" done.\n"); 224 | else { 225 | stop_progress_meter(); 226 | free(msg); 227 | } 228 | 229 | fetchIO_close(f); 230 | 231 | if (written != st.size) { 232 | fprintf(stderr, "download error: %s truncated\n", pkg_url); 233 | return -1; 234 | } 235 | 236 | return written; 237 | } 238 | -------------------------------------------------------------------------------- /external/automatic.c: -------------------------------------------------------------------------------- 1 | /* NetBSD: automatic.c,v 1.5 2009/02/02 12:35:01 joerg Exp */ 2 | 3 | /*- 4 | * Copyright (c) 2005 The NetBSD Foundation, Inc. 5 | * All rights reserved. 6 | * 7 | * This code is derived from software contributed to The NetBSD Foundation 8 | * by Dieter Baron and Thomas Klausner. 9 | * 10 | * Redistribution and use in source and binary forms, with or without 11 | * modification, are permitted provided that the following conditions 12 | * are met: 13 | * 1. Redistributions of source code must retain the above copyright 14 | * notice, this list of conditions and the following disclaimer. 15 | * 2. Redistributions in binary form must reproduce the above copyright 16 | * notice, this list of conditions and the following disclaimer in the 17 | * documentation and/or other materials provided with the distribution. 18 | * 3. Neither the name of The NetBSD Foundation nor the names of its 19 | * contributors may be used to endorse or promote products derived 20 | * from this software without specific prior written permission. 21 | * 22 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 23 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 24 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 25 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 26 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 29 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 30 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 | * POSSIBILITY OF SUCH DAMAGE. 33 | */ 34 | 35 | #include "lib.h" 36 | 37 | Boolean 38 | is_automatic_installed(const char *pkg) 39 | { 40 | char *filename, *value; 41 | Boolean ret; 42 | 43 | assert(pkg[0] != '/'); 44 | 45 | filename = pkgdb_pkg_file(pkg, INSTALLED_INFO_FNAME); 46 | 47 | value = var_get(filename, AUTOMATIC_VARNAME); 48 | 49 | if (value && strcasecmp(value, "yes") == 0) 50 | ret = TRUE; 51 | else 52 | ret = FALSE; 53 | 54 | free(value); 55 | free(filename); 56 | 57 | return ret; 58 | } 59 | 60 | int 61 | mark_as_automatic_installed(const char *pkg, int value) 62 | { 63 | char *filename; 64 | int retval; 65 | 66 | assert(pkg[0] != '/'); 67 | 68 | filename = pkgdb_pkg_file(pkg, INSTALLED_INFO_FNAME); 69 | 70 | retval = var_set(filename, AUTOMATIC_VARNAME, value ? "yes" : NULL); 71 | 72 | free(filename); 73 | 74 | return retval; 75 | } 76 | -------------------------------------------------------------------------------- /external/dewey.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NetBSDfr/pkgin/0f9268a20d8b53bd41672f19f46629ec5f1a6ff0/external/dewey.c -------------------------------------------------------------------------------- /external/dewey.h: -------------------------------------------------------------------------------- 1 | /* NetBSD: dewey.h,v 1.2 2007/04/16 12:55:35 joerg Exp */ 2 | 3 | #ifndef _INST_LIB_DEWEY_H_ 4 | #define _INST_LIB_DEWEY_H_ 5 | 6 | int dewey_cmp(const char *, int, const char *); 7 | int dewey_match(const char *, const char *); 8 | int dewey_mktest(int *, const char *); 9 | 10 | enum { 11 | DEWEY_LT, 12 | DEWEY_LE, 13 | DEWEY_EQ, 14 | DEWEY_GE, 15 | DEWEY_GT, 16 | DEWEY_NE 17 | }; 18 | 19 | #endif /* _INST_LIB_DEWEY_H_ */ 20 | -------------------------------------------------------------------------------- /external/fexec.c: -------------------------------------------------------------------------------- 1 | /* NetBSD: fexec.c,v 1.12 2009/08/02 17:56:45 joerg Exp */ 2 | 3 | /*- 4 | * Copyright (c) 2003 The NetBSD Foundation, Inc. 5 | * All rights reserved. 6 | * 7 | * This code is derived from software contributed to The NetBSD Foundation 8 | * by Matthias Scheler. 9 | * 10 | * Redistribution and use in source and binary forms, with or without 11 | * modification, are permitted provided that the following conditions 12 | * are met: 13 | * 1. Redistributions of source code must retain the above copyright 14 | * notice, this list of conditions and the following disclaimer. 15 | * 2. Redistributions in binary form must reproduce the above copyright 16 | * notice, this list of conditions and the following disclaimer in the 17 | * documentation and/or other materials provided with the distribution. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 | * POSSIBILITY OF SUCH DAMAGE. 30 | */ 31 | 32 | #include "lib.h" 33 | 34 | /* 35 | * Newer macOS releases are not able to correctly handle vfork() when the 36 | * underlying file is changed or removed, as is the case when upgrading 37 | * pkg_install itself. The manual pages suggest using posix_spawn() 38 | * instead, which seems to work ok. 39 | */ 40 | #if defined(__APPLE__) && \ 41 | ((__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__-0) >= 1050) 42 | #define FEXEC_USE_POSIX_SPAWN 1 43 | #else 44 | #define FEXEC_USE_POSIX_SPAWN 0 45 | #endif 46 | 47 | #if FEXEC_USE_POSIX_SPAWN 48 | #include 49 | extern char **environ; 50 | 51 | #ifndef O_CLOEXEC 52 | #define O_CLOEXEC 0 53 | #endif 54 | 55 | #ifndef O_DIRECTORY 56 | #define O_DIRECTORY 0 57 | #endif 58 | #endif 59 | 60 | static int vfcexec(const char *, int, const char *, va_list); 61 | 62 | /* 63 | * fork, then change current working directory to path and 64 | * execute the command and arguments in the argv array. 65 | * wait for the command to finish, then return the exit status. 66 | * 67 | * macOS uses posix_spawn() instead due to reasons explained above. 68 | */ 69 | int 70 | pfcexec(const char *path, const char *file, const char **argv) 71 | { 72 | pid_t child; 73 | int status; 74 | 75 | #if FEXEC_USE_POSIX_SPAWN 76 | int prevcwd; 77 | 78 | if ((prevcwd = open(".", O_RDONLY|O_CLOEXEC|O_DIRECTORY)) < 0) { 79 | warn("open prevcwd failed"); 80 | return -1; 81 | } 82 | 83 | if ((path != NULL) && (chdir(path) < 0)) { 84 | warn("chdir %s failed", path); 85 | return -1; 86 | } 87 | 88 | if (posix_spawn(&child, file, NULL, NULL, (char **)argv, environ) < 0) { 89 | warn("posix_spawn failed"); 90 | return -1; 91 | } 92 | 93 | if (fchdir(prevcwd) < 0) { 94 | warn("fchdir prevcwd failed"); 95 | return -1; 96 | } 97 | 98 | (void)close(prevcwd); 99 | #else 100 | child = vfork(); 101 | switch (child) { 102 | case 0: 103 | if ((path != NULL) && (chdir(path) < 0)) 104 | _exit(127); 105 | 106 | (void)execvp(file, __UNCONST(argv)); 107 | _exit(127); 108 | /* NOTREACHED */ 109 | case -1: 110 | return -1; 111 | } 112 | #endif 113 | 114 | while (waitpid(child, &status, 0) < 0) { 115 | if (errno != EINTR) 116 | return -1; 117 | } 118 | 119 | if (!WIFEXITED(status)) 120 | return -1; 121 | 122 | return WEXITSTATUS(status); 123 | } 124 | 125 | static int 126 | vfcexec(const char *path, int skipempty, const char *arg, va_list ap) 127 | { 128 | const char **argv; 129 | size_t argv_size, argc; 130 | int retval; 131 | 132 | argv_size = 16; 133 | argv = xcalloc(argv_size, sizeof(*argv)); 134 | 135 | argv[0] = arg; 136 | argc = 1; 137 | 138 | do { 139 | if (argc == argv_size) { 140 | argv_size *= 2; 141 | argv = xrealloc(argv, argv_size * sizeof(*argv)); 142 | } 143 | arg = va_arg(ap, const char *); 144 | if (skipempty && arg && strlen(arg) == 0) 145 | continue; 146 | argv[argc++] = arg; 147 | } while (arg != NULL); 148 | 149 | retval = pfcexec(path, argv[0], argv); 150 | free(argv); 151 | return retval; 152 | } 153 | 154 | int 155 | fexec(const char *arg, ...) 156 | { 157 | va_list ap; 158 | int result; 159 | 160 | va_start(ap, arg); 161 | result = vfcexec(NULL, 0, arg, ap); 162 | va_end(ap); 163 | 164 | return result; 165 | } 166 | 167 | int 168 | fexec_skipempty(const char *arg, ...) 169 | { 170 | va_list ap; 171 | int result; 172 | 173 | va_start(ap, arg); 174 | result = vfcexec(NULL, 1, arg, ap); 175 | va_end(ap); 176 | 177 | return result; 178 | } 179 | 180 | int 181 | fcexec(const char *path, const char *arg, ...) 182 | { 183 | va_list ap; 184 | int result; 185 | 186 | va_start(ap, arg); 187 | result = vfcexec(path, 0, arg, ap); 188 | va_end(ap); 189 | 190 | return result; 191 | } 192 | -------------------------------------------------------------------------------- /external/humanize_number.c: -------------------------------------------------------------------------------- 1 | /* $NetBSD: humanize_number.c,v 1.18 2019/03/11 15:10:51 kre Exp $ */ 2 | 3 | /* 4 | * Copyright (c) 1997, 1998, 1999, 2002 The NetBSD Foundation, Inc. 5 | * All rights reserved. 6 | * 7 | * This code is derived from software contributed to The NetBSD Foundation 8 | * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 9 | * NASA Ames Research Center, by Luke Mewburn and by Tomas Svensson. 10 | * 11 | * Redistribution and use in source and binary forms, with or without 12 | * modification, are permitted provided that the following conditions 13 | * are met: 14 | * 1. Redistributions of source code must retain the above copyright 15 | * notice, this list of conditions and the following disclaimer. 16 | * 2. Redistributions in binary form must reproduce the above copyright 17 | * notice, this list of conditions and the following disclaimer in the 18 | * documentation and/or other materials provided with the distribution. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 | * POSSIBILITY OF SUCH DAMAGE. 31 | */ 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | #include "humanize_number.h" 40 | 41 | int 42 | humanize_number(char *buf, size_t len, int64_t bytes, 43 | const char *suffix, int scale, int flags) 44 | { 45 | const char *prefixes, *sep; 46 | int b, i, r, s1, s2, sign; 47 | int64_t divisor, max, post = 1; 48 | size_t baselen; 49 | int maxscale; 50 | 51 | if (suffix == NULL) 52 | suffix = ""; 53 | 54 | if (flags & HN_DIVISOR_1000) { 55 | /* SI for decimal multiplies */ 56 | divisor = 1000; 57 | if (flags & HN_B) 58 | prefixes = "B\0k\0M\0G\0T\0P\0E"; 59 | else 60 | prefixes = "\0\0k\0M\0G\0T\0P\0E"; 61 | } else { 62 | /* 63 | * binary multiplies 64 | * XXX IEC 60027-2 recommends Ki, Mi, Gi... 65 | */ 66 | divisor = 1024; 67 | if (flags & HN_B) 68 | prefixes = "B\0K\0M\0G\0T\0P\0E"; 69 | else 70 | prefixes = "\0\0K\0M\0G\0T\0P\0E"; 71 | } 72 | 73 | #define SCALE2PREFIX(scale) (&prefixes[(scale) << 1]) 74 | maxscale = 6; 75 | 76 | if (scale < 0 || (scale > maxscale && 77 | (scale & (HN_AUTOSCALE | HN_GETSCALE)) == 0)) 78 | return (-1); 79 | 80 | if (buf == NULL) 81 | return (-1); 82 | 83 | if (len > 0) 84 | buf[0] = '\0'; 85 | 86 | if (bytes < 0) { 87 | sign = -1; 88 | baselen = 3; /* sign, digit, prefix */ 89 | if (-bytes < INT64_MAX / 100) 90 | bytes *= -100; 91 | else { 92 | bytes = -bytes; 93 | post = 100; 94 | baselen += 2; 95 | } 96 | } else { 97 | sign = 1; 98 | baselen = 2; /* digit, prefix */ 99 | if (bytes < INT64_MAX / 100) 100 | bytes *= 100; 101 | else { 102 | post = 100; 103 | baselen += 2; 104 | } 105 | } 106 | if (flags & HN_NOSPACE) 107 | sep = ""; 108 | else { 109 | sep = " "; 110 | baselen++; 111 | } 112 | baselen += strlen(suffix); 113 | 114 | /* Check if enough room for `x y' + suffix + `\0' */ 115 | if (len < baselen + 1) 116 | return (-1); 117 | 118 | if (scale & (HN_AUTOSCALE | HN_GETSCALE)) { 119 | /* 120 | * 19 is number of digits in biggest possible int64_t 121 | * If we don't do this, the calc of max just below can 122 | * overflow, leading to absurd results. If the buffer 123 | * is big enough for the number, simply use it, no scaling. 124 | */ 125 | if (len - baselen > 19) 126 | i = 0; 127 | else { 128 | /* See if there are additional columns to be used. */ 129 | for (max = 100, i = len - baselen; i-- > 0;) 130 | max *= 10; 131 | 132 | /* 133 | * Divide the number until it fits the avail buffer. 134 | * If there will be an overflow by the rounding below, 135 | * (the "-50") divide once more. 136 | */ 137 | for (i = 0; bytes >= max - 50 && i < maxscale; i++) 138 | bytes /= divisor; 139 | } 140 | if (scale & HN_GETSCALE) { 141 | return i; 142 | } 143 | } else { 144 | /* XXX 145 | * we already know scale <= maxscale, so 146 | * i < scale ==> i < maxscale 147 | */ 148 | for (i = 0; i < scale && i < maxscale; i++) 149 | bytes /= divisor; 150 | } 151 | 152 | if (i == 0) { 153 | /* 154 | * Cannot go the bytes *= post route, as 155 | * that can cause overflow of bytes 156 | * 157 | * but if we already scaled up, undo that. 158 | */ 159 | if (post == 1) 160 | bytes /= 100; 161 | 162 | r = snprintf(buf, len, "%" PRId64 "%s%s%s", 163 | sign * bytes, sep, SCALE2PREFIX(0), suffix); 164 | } else { 165 | /* 166 | * Here this is safe, as if i > 0, we have already 167 | * divided bytes by at least 1000, post <= 100, so ... 168 | */ 169 | bytes *= post; 170 | 171 | /* If a value <= 9.9 after rounding and ... */ 172 | if (bytes < 995 && i > 0 && flags & HN_DECIMAL) { 173 | /* baselen + \0 + .N */ 174 | if (len < baselen + 1 + 1 + 175 | strlen(localeconv()->decimal_point)) 176 | return (-1); 177 | b = ((int)bytes + 5) / 10; 178 | s1 = b / 10; 179 | s2 = b % 10; 180 | r = snprintf(buf, len, "%d%s%d%s%s%s", 181 | sign * s1, localeconv()->decimal_point, s2, 182 | sep, SCALE2PREFIX(i), suffix); 183 | } else 184 | r = snprintf(buf, len, "%" PRId64 "%s%s%s", 185 | sign * ((bytes + 50) / 100), 186 | sep, SCALE2PREFIX(i), suffix); 187 | } 188 | 189 | if ((size_t)r > len) 190 | r = -1; 191 | 192 | return (r); 193 | } 194 | -------------------------------------------------------------------------------- /external/humanize_number.h: -------------------------------------------------------------------------------- 1 | #ifndef _HUMANIZE_NUMBER_H_ 2 | #define _HUMANIZE_NUMBER_H_ 3 | 4 | #define HN_DECIMAL 0x01 5 | #define HN_NOSPACE 0x02 6 | #define HN_B 0x04 7 | #define HN_DIVISOR_1000 0x08 8 | 9 | #define HN_GETSCALE 0x10 10 | #define HN_AUTOSCALE 0x20 11 | 12 | int humanize_number(char *, size_t, int64_t, const char *, int, int); 13 | int dehumanize_number(const char *, int64_t *); 14 | 15 | #endif /* !_HUMANIZE_NUMBER_H_ */ 16 | -------------------------------------------------------------------------------- /external/lib.h: -------------------------------------------------------------------------------- 1 | /* NetBSD: lib.h,v 1.69 2018/02/26 23:45:02 ginsbach Exp */ 2 | 3 | /* from FreeBSD Id: lib.h,v 1.25 1997/10/08 07:48:03 charnier Exp */ 4 | 5 | /* 6 | * FreeBSD install - a package for the installation and maintainance 7 | * of non-core utilities. 8 | * 9 | * Redistribution and use in source and binary forms, with or without 10 | * modification, are permitted provided that the following conditions 11 | * are met: 12 | * 1. Redistributions of source code must retain the above copyright 13 | * notice, this list of conditions and the following disclaimer. 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 | * Jordan K. Hubbard 19 | * 18 July 1993 20 | * 21 | * Include and define various things wanted by the library routines. 22 | */ 23 | 24 | /* 25 | * This file has been stripped to remove anything not required by pkgin. 26 | */ 27 | 28 | #ifndef _INST_LIB_LIB_H_ 29 | #define _INST_LIB_LIB_H_ 30 | 31 | #include "config.h" 32 | 33 | /* 34 | * Include our copy of queue.h before nbcompat pulls in its version. 35 | */ 36 | #include "queue.h" 37 | 38 | #if HAVE_NBCOMPAT_H 39 | #include 40 | #else 41 | #include 42 | #endif 43 | 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | 56 | #include 57 | #include 58 | 59 | /* Macros */ 60 | #ifndef __UNCONST 61 | #define __UNCONST(a) ((void *)(unsigned long)(const void *)(a)) 62 | #endif 63 | 64 | #define SUCCESS (0) 65 | #define FAIL (-1) 66 | 67 | #ifndef TRUE 68 | #define TRUE (1) 69 | #endif 70 | 71 | #ifndef FALSE 72 | #define FALSE (0) 73 | #endif 74 | 75 | #ifndef DEF_UMASK 76 | #define DEF_UMASK 022 77 | #endif 78 | #ifndef PATH_MAX 79 | # ifdef MAXPATHLEN 80 | # define PATH_MAX MAXPATHLEN 81 | # else 82 | # define PATH_MAX 1024 83 | # endif 84 | #endif 85 | 86 | enum { 87 | MaxPathSize = PATH_MAX 88 | }; 89 | 90 | /* The names of our "special" files */ 91 | #define CONTENTS_FNAME "+CONTENTS" 92 | #define COMMENT_FNAME "+COMMENT" 93 | #define DESC_FNAME "+DESC" 94 | #define INSTALL_FNAME "+INSTALL" 95 | #define DEINSTALL_FNAME "+DEINSTALL" 96 | #define REQUIRED_BY_FNAME "+REQUIRED_BY" 97 | #define REQUIRED_BY_FNAME_TMP "+REQUIRED_BY.tmp" 98 | #define DISPLAY_FNAME "+DISPLAY" 99 | #define MTREE_FNAME "+MTREE_DIRS" 100 | #define BUILD_VERSION_FNAME "+BUILD_VERSION" 101 | #define BUILD_INFO_FNAME "+BUILD_INFO" 102 | #define INSTALLED_INFO_FNAME "+INSTALLED_INFO" 103 | #define SIZE_PKG_FNAME "+SIZE_PKG" 104 | #define SIZE_ALL_FNAME "+SIZE_ALL" 105 | #define PRESERVE_FNAME "+PRESERVE" 106 | 107 | /* The names of special variables */ 108 | #define AUTOMATIC_VARNAME "automatic" 109 | 110 | /* Prefix for extended PLIST cmd */ 111 | #define CMD_CHAR '@' 112 | 113 | typedef enum pl_ent_t { 114 | PLIST_SHOW_ALL = -1, 115 | PLIST_FILE, /* 0 */ 116 | PLIST_CWD, /* 1 */ 117 | PLIST_CMD, /* 2 */ 118 | PLIST_CHMOD, /* 3 */ 119 | PLIST_CHOWN, /* 4 */ 120 | PLIST_CHGRP, /* 5 */ 121 | PLIST_COMMENT, /* 6 */ 122 | PLIST_IGNORE, /* 7 */ 123 | PLIST_NAME, /* 8 */ 124 | PLIST_UNEXEC, /* 9 */ 125 | PLIST_SRC, /* 10 */ 126 | PLIST_DISPLAY, /* 11 */ 127 | PLIST_PKGDEP, /* 12 */ 128 | PLIST_DIR_RM, /* 13 */ 129 | PLIST_OPTION, /* 14 */ 130 | PLIST_PKGCFL, /* 15 */ 131 | PLIST_BLDDEP, /* 16 */ 132 | PLIST_PKGDIR /* 17 */ 133 | } pl_ent_t; 134 | 135 | /* Types */ 136 | typedef unsigned int Boolean; 137 | 138 | /* This structure describes a packing list entry */ 139 | typedef struct plist_t { 140 | struct plist_t *prev; /* previous entry */ 141 | struct plist_t *next; /* next entry */ 142 | char *name; /* name of entry */ 143 | Boolean marked; /* whether entry has been marked */ 144 | pl_ent_t type; /* type of entry */ 145 | } plist_t; 146 | 147 | /* This structure describes a package's complete packing list */ 148 | typedef struct package_t { 149 | plist_t *head; /* head of list */ 150 | plist_t *tail; /* tail of list */ 151 | } package_t; 152 | 153 | #define SYMLINK_HEADER "Symlink:" 154 | #define CHECKSUM_HEADER "MD5:" 155 | 156 | enum { 157 | ChecksumHeaderLen = 4, /* strlen(CHECKSUM_HEADER) */ 158 | SymlinkHeaderLen = 8, /* strlen(SYMLINK_HEADER) */ 159 | ChecksumLen = 16, 160 | LegibleChecksumLen = 33 161 | }; 162 | 163 | /* List of packages */ 164 | typedef struct _lpkg_t { 165 | TAILQ_ENTRY(_lpkg_t) lp_link; 166 | char *lp_name; 167 | } lpkg_t; 168 | TAILQ_HEAD(_lpkg_head_t, _lpkg_t); 169 | typedef struct _lpkg_head_t lpkg_head_t; 170 | 171 | /* 172 | * To improve performance when handling lists containing a large number of 173 | * packages, it can be beneficial to use hashed lookups to avoid excessive 174 | * strcmp() calls when searching for existing entries. 175 | * 176 | * The simple hashing function below uses the first 3 characters of either a 177 | * pattern match or package name (as they are guaranteed to exist). 178 | * 179 | * Based on pkgsrc package names across the tree, this can still result in 180 | * somewhat uneven distribution due to high numbers of packages beginning with 181 | * "p5-", "php", "py-" etc, and so there are diminishing returns when trying to 182 | * use a hash size larger than around 16 or so. 183 | */ 184 | #define PKG_HASH_SIZE 16 185 | #define PKG_HASH_ENTRY(x) (((unsigned char)(x)[0] \ 186 | + (unsigned char)(x)[1] * 257 \ 187 | + (unsigned char)(x)[2] * 65537) \ 188 | & (PKG_HASH_SIZE - 1)) 189 | 190 | /* Prototypes */ 191 | /* Misc */ 192 | int fexec(const char *, ...); 193 | int fexec_skipempty(const char *, ...); 194 | int fcexec(const char *, const char *, ...); 195 | int pfcexec(const char *, const char *, const char **); 196 | 197 | /* variables file handling */ 198 | 199 | char *var_get(const char *, const char *); 200 | char *var_get_memory(const char *, const char *); 201 | int var_set(const char *, const char *, const char *); 202 | int var_copy_list(const char *, const char **); 203 | 204 | /* automatically installed as dependency */ 205 | 206 | Boolean is_automatic_installed(const char *); 207 | int mark_as_automatic_installed(const char *, int); 208 | 209 | /* String */ 210 | int pkg_match(const char *, const char *); 211 | int pkg_order(const char *, const char *, const char *); 212 | int quick_pkg_match(const char *, const char *); 213 | 214 | /* Iterator functions */ 215 | int iterate_pkg_db(int (*)(const char *, void *), void *); 216 | char *find_matching_installed_pkg(const char *, int, int); 217 | 218 | /* Packing list */ 219 | plist_t *new_plist_entry(void); 220 | plist_t *last_plist(package_t *); 221 | plist_t *find_plist(package_t *, pl_ent_t); 222 | char *find_plist_option(package_t *, const char *); 223 | void plist_delete(package_t *, Boolean, pl_ent_t, char *); 224 | void free_plist(package_t *); 225 | void mark_plist(package_t *); 226 | void csum_plist_entry(char *, plist_t *); 227 | void add_plist(package_t *, pl_ent_t, const char *); 228 | void add_plist_top(package_t *, pl_ent_t, const char *); 229 | void delete_plist(package_t *, Boolean, pl_ent_t, char *); 230 | void write_plist(package_t *, FILE *, char *); 231 | void stringify_plist(package_t *, char **, size_t *, const char *); 232 | void parse_plist(package_t *, const char *); 233 | void read_plist(package_t *, FILE *); 234 | void append_plist(package_t *, FILE *); 235 | int delete_package(Boolean, package_t *, Boolean, const char *); 236 | 237 | /* Package Database */ 238 | int pkgdb_open(int); 239 | const char *pkgdb_get_dir(void); 240 | /* 241 | * Priorities: 242 | * 0 builtin default 243 | * 1 config file 244 | * 2 environment 245 | * 3 command line 246 | */ 247 | void pkgdb_set_dir(const char *, int); 248 | char *pkgdb_pkg_dir(const char *); 249 | char *pkgdb_pkg_file(const char *, const char *); 250 | 251 | /* List of packages functions */ 252 | lpkg_t *alloc_lpkg(const char *); 253 | lpkg_t *find_on_queue(lpkg_head_t *, const char *); 254 | void free_lpkg(lpkg_t *); 255 | 256 | /* Helper functions for memory allocation */ 257 | char *xstrdup(const char *); 258 | void *xrealloc(void *, size_t); 259 | void *xcalloc(size_t, size_t); 260 | void *xmalloc(size_t); 261 | #if defined(__GNUC__) && __GNUC__ >= 2 262 | char *xasprintf(const char *, ...) 263 | __attribute__((__format__(__printf__, 1, 2))); 264 | #else 265 | char *xasprintf(const char *, ...); 266 | #endif 267 | 268 | #endif /* _INST_LIB_LIB_H_ */ 269 | -------------------------------------------------------------------------------- /external/lpkg.c: -------------------------------------------------------------------------------- 1 | /* $NetBSD: lpkg.c,v 1.6 2009/02/02 12:35:01 joerg Exp $ */ 2 | 3 | /* 4 | * Copyright (c) 1999 Christian E. Hopps 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 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 | * 3. The name of the author may not be used to endorse or promote products 16 | * derived from this software without specific prior written permission 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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 | * Package-list auxiliary functions 30 | */ 31 | 32 | #if HAVE_CONFIG_H 33 | #include "config.h" 34 | #endif 35 | #ifdef HAVE_NBCOMPAT_H 36 | #include 37 | #endif 38 | #if HAVE_ERR_H 39 | #include 40 | #endif 41 | #include "lib.h" 42 | 43 | /* 44 | * Add a package to the (add/recursive delete) list 45 | */ 46 | lpkg_t * 47 | alloc_lpkg(const char *pkgname) 48 | { 49 | lpkg_t *lpp; 50 | 51 | lpp = xmalloc(sizeof(*lpp)); 52 | lpp->lp_name = xstrdup(pkgname); 53 | return (lpp); 54 | } 55 | 56 | void 57 | free_lpkg(lpkg_t *lpp) 58 | { 59 | free(lpp->lp_name); 60 | free(lpp); 61 | } 62 | 63 | lpkg_t * 64 | find_on_queue(lpkg_head_t *qp, const char *name) 65 | { 66 | lpkg_t *lpp; 67 | 68 | for (lpp = TAILQ_FIRST(qp); lpp; lpp = TAILQ_NEXT(lpp, lp_link)) 69 | if (!strcmp(name, lpp->lp_name)) 70 | return (lpp); 71 | return (0); 72 | } 73 | -------------------------------------------------------------------------------- /external/opattern.c: -------------------------------------------------------------------------------- 1 | /* NetBSD: opattern.c,v 1.6 2012/01/28 12:33:05 joerg Exp */ 2 | 3 | /* 4 | * FreeBSD install - a package for the installation and maintainance 5 | * of non-core utilities. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 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 | * Jordan K. Hubbard 17 | * 18 July 1993 18 | * 19 | * Miscellaneous string utilities. 20 | * 21 | */ 22 | 23 | #include "lib.h" 24 | #include "dewey.h" 25 | 26 | /* 27 | * Perform alternate match on "pkg" against "pattern", 28 | * calling pkg_match (recursively) to resolve any other patterns. 29 | * Return 1 on match, 0 otherwise 30 | */ 31 | static int 32 | alternate_match(const char *pattern, const char *pkg) 33 | { 34 | char *sep; 35 | char buf[MaxPathSize]; 36 | char *last; 37 | char *alt; 38 | char *cp; 39 | int cnt; 40 | int found; 41 | 42 | if ((sep = strchr(pattern, '{')) == (char *) NULL) { 43 | errx(EXIT_FAILURE, "alternate_match(): '{' expected in `%s'", pattern); 44 | } 45 | (void) strncpy(buf, pattern, (size_t) (sep - pattern)); 46 | alt = &buf[sep - pattern]; 47 | last = (char *) NULL; 48 | for (cnt = 0, cp = sep; *cp && last == (char *) NULL; cp++) { 49 | if (*cp == '{') { 50 | cnt++; 51 | } else if (*cp == '}' && --cnt == 0 && last == (char *) NULL) { 52 | last = cp + 1; 53 | } 54 | } 55 | if (cnt != 0) { 56 | errx(EXIT_FAILURE, "Malformed alternate `%s'", pattern); 57 | } 58 | for (found = 0, cp = sep + 1; *sep != '}'; cp = sep + 1) { 59 | for (cnt = 0, sep = cp; cnt > 0 || (cnt == 0 && *sep != '}' && *sep != ','); sep++) { 60 | if (*sep == '{') { 61 | cnt++; 62 | } else if (*sep == '}') { 63 | cnt--; 64 | } 65 | } 66 | (void) snprintf(alt, sizeof(buf) - (alt - buf), "%.*s%s", (int) (sep - cp), cp, last); 67 | if (pkg_match(buf, pkg) == 1) { 68 | found = 1; 69 | } 70 | } 71 | return found; 72 | } 73 | 74 | /* 75 | * Perform glob match on "pkg" against "pattern". 76 | * Return 1 on match, 0 otherwise 77 | */ 78 | static int 79 | glob_match(const char *pattern, const char *pkg) 80 | { 81 | return fnmatch(pattern, pkg, FNM_PERIOD) == 0; 82 | } 83 | 84 | /* 85 | * Perform simple match on "pkg" against "pattern". 86 | * Return 1 on match, 0 otherwise 87 | */ 88 | static int 89 | simple_match(const char *pattern, const char *pkg) 90 | { 91 | return strcmp(pattern, pkg) == 0; 92 | } 93 | 94 | /* 95 | * Performs a fast check if pattern can ever match pkg. 96 | * Returns 1 if a match is possible and 0 otherwise. 97 | */ 98 | int 99 | quick_pkg_match(const char *pattern, const char *pkg) 100 | { 101 | #define simple(x) (isalnum((unsigned char)(x)) || (x) == '-') 102 | /* 103 | * In pkgin we often match over the entire remote repository, and so it 104 | * is optimal to extend this faster check to more characters and reduce 105 | * the number of candidate matches, as later pkg_match checks are much 106 | * more expensive. 107 | * 108 | * 8 loops are currrently chosen as that is the sweet spot for a 2022Q4 109 | * repository with around 24,000 packages, limiting the maximum number 110 | * of possible matches to around 120: 111 | * 112 | * $ for i in {2..10}; do 113 | * > printf "%3s:" ${i} 114 | * > pkgin avail | cut -c1-${i} | sort | uniq -c | sort -n | tail -1 115 | * > done 116 | * 117 | * 2: 7144 py 118 | * 3: 6415 py3 119 | * 4: 3199 py31 120 | * 5: 1608 py38- 121 | * 6: 1607 py310- 122 | * 7: 804 ruby27- 123 | * 8: 119 p5-Test- 124 | * 9: 104 py39-tryt 125 | * 10: 104 py39-tryto 126 | */ 127 | for (int i = 0; i < 8; i++) { 128 | if (!simple(pattern[i])) 129 | return 1; 130 | if (pattern[i] != pkg[i]) 131 | return 0; 132 | } 133 | return 1; 134 | #undef simple 135 | } 136 | 137 | /* 138 | * Match pkg against pattern, return 1 if matching, 0 else 139 | */ 140 | int 141 | pkg_match(const char *pattern, const char *pkg) 142 | { 143 | if (!quick_pkg_match(pattern, pkg)) 144 | return 0; 145 | 146 | if (strchr(pattern, '{') != (char *) NULL) { 147 | /* emulate csh-type alternates */ 148 | return alternate_match(pattern, pkg); 149 | } 150 | if (strpbrk(pattern, "<>") != (char *) NULL) { 151 | int ret; 152 | 153 | /* perform relational dewey match on version number */ 154 | ret = dewey_match(pattern, pkg); 155 | if (ret < 0) 156 | errx(EXIT_FAILURE, "dewey_match returned error"); 157 | return ret; 158 | } 159 | if (strpbrk(pattern, "*?[]") != (char *) NULL) { 160 | /* glob match */ 161 | if (glob_match(pattern, pkg)) 162 | return 1; 163 | } 164 | 165 | /* no alternate, dewey or glob match -> simple compare */ 166 | if (simple_match(pattern, pkg)) 167 | return 1; 168 | 169 | /* globbing patterns and simple matches may be specified with or 170 | * without the version number, so check for both cases. */ 171 | 172 | { 173 | char *pattern_ver; 174 | int retval; 175 | 176 | pattern_ver = xasprintf("%s-[0-9]*", pattern); 177 | retval = glob_match(pattern_ver, pkg); 178 | free(pattern_ver); 179 | return retval; 180 | } 181 | } 182 | 183 | int 184 | pkg_order(const char *pattern, const char *first_pkg, const char *second_pkg) 185 | { 186 | const char *first_version; 187 | const char *second_version; 188 | 189 | if (first_pkg == NULL && second_pkg == NULL) 190 | return 0; 191 | 192 | if (first_pkg == NULL) 193 | return pkg_match(pattern, second_pkg) ? 2 : 0; 194 | if (second_pkg == NULL) 195 | return pkg_match(pattern, first_pkg) ? 1 : 0; 196 | 197 | first_version = strrchr(first_pkg, '-'); 198 | second_version = strrchr(second_pkg, '-'); 199 | 200 | if (first_version == NULL || !pkg_match(pattern, first_pkg)) 201 | return pkg_match(pattern, second_pkg) ? 2 : 0; 202 | 203 | if (second_version == NULL || !pkg_match(pattern, second_pkg)) 204 | return pkg_match(pattern, first_pkg) ? 1 : 0; 205 | 206 | if (dewey_cmp(first_version + 1, DEWEY_GT, second_version + 1)) 207 | return 1; 208 | else if (dewey_cmp(first_version + 1, DEWEY_LT, second_version + 1)) 209 | return 2; 210 | else if (strcmp(first_pkg, second_pkg) < 0) 211 | return 1; 212 | else 213 | return 2; 214 | } 215 | -------------------------------------------------------------------------------- /external/pkgdb.c: -------------------------------------------------------------------------------- 1 | /* NetBSD: pkgdb.c,v 1.39 2010/04/20 21:22:38 joerg Exp */ 2 | 3 | /*- 4 | * Copyright (c) 1999-2010 The NetBSD Foundation, Inc. 5 | * All rights reserved. 6 | * 7 | * This code is derived from software contributed to The NetBSD Foundation 8 | * by Hubert Feyrer . 9 | * 10 | * Redistribution and use in source and binary forms, with or without 11 | * modification, are permitted provided that the following conditions 12 | * are met: 13 | * 1. Redistributions of source code must retain the above copyright 14 | * notice, this list of conditions and the following disclaimer. 15 | * 2. Redistributions in binary form must reproduce the above copyright 16 | * notice, this list of conditions and the following disclaimer in the 17 | * documentation and/or other materials provided with the distribution. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 | * POSSIBILITY OF SUCH DAMAGE. 30 | */ 31 | 32 | /* 33 | * This is a much simplified version of pkgdb.c that provides what is required 34 | * by the other files we have pulled from pkg_install. It is also modified to 35 | * set pkgdb_dir explicitly to what we have parsed from pkg_admin(1). 36 | */ 37 | 38 | #include "lib.h" 39 | 40 | static char *pkgdb_dir = NULL; 41 | static int pkgdb_dir_prio = 0; 42 | 43 | const char * 44 | pkgdb_get_dir(void) 45 | { 46 | return pkgdb_dir; 47 | } 48 | 49 | void 50 | pkgdb_set_dir(const char *dir, int prio) 51 | { 52 | if (prio < pkgdb_dir_prio) 53 | return; 54 | 55 | pkgdb_dir_prio = prio; 56 | 57 | if (dir == pkgdb_dir) 58 | return; 59 | 60 | pkgdb_dir = xstrdup(dir); 61 | } 62 | 63 | char * 64 | pkgdb_pkg_file(const char *pkg, const char *file) 65 | { 66 | return xasprintf("%s/%s/%s", pkgdb_get_dir(), pkg, file); 67 | } 68 | -------------------------------------------------------------------------------- /external/progressmeter.c: -------------------------------------------------------------------------------- 1 | /* NetBSD: progressmeter.c,v 1.9 2008/08/05 14:13:34 simonb Exp */ 2 | /* OpenBSD: progressmeter.c,v 1.37 2006/08/03 03:34:42 deraadt Exp */ 3 | /* 4 | * Copyright (c) 2003 Nils Nordman. 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 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | #include "progressmeter.h" 39 | 40 | #define DEFAULT_WINSIZE 80 41 | #define MAX_WINSIZE 512 42 | #define PADDING 1 /* padding between the progress indicators */ 43 | #define UPDATE_INTERVAL 1 /* update the progress meter every second */ 44 | #define STALL_TIME 5 /* we're stalled after this many seconds */ 45 | 46 | /* determines whether we can output to the terminal */ 47 | static int can_output(void); 48 | 49 | /* formats and inserts the specified size into the given buffer */ 50 | static void format_size(char *, int, off_t); 51 | static void format_rate(char *, int, off_t); 52 | 53 | /* window resizing */ 54 | static void sig_winch(int); 55 | static void setscreensize(void); 56 | 57 | /* updates the progressmeter to reflect the current state of the transfer */ 58 | void refresh_progress_meter(void); 59 | 60 | /* signal handler for updating the progress meter */ 61 | static void update_progress_meter(int); 62 | 63 | static time_t start; /* start progress */ 64 | static time_t last_update; /* last progress update */ 65 | static const char *file; /* name of the file being transferred */ 66 | static off_t start_pos; /* initial position of transfer */ 67 | static off_t end_pos; /* ending position of transfer */ 68 | static off_t cur_pos; /* transfer position as of last refresh */ 69 | static volatile off_t *counter; /* progress counter */ 70 | static long stalled; /* how long we have been stalled */ 71 | static int bytes_per_second; /* current speed in bytes per second */ 72 | static int win_size; /* terminal window size */ 73 | static volatile sig_atomic_t win_resized; /* for window resizing */ 74 | 75 | /* units for format_size */ 76 | static const char unit[] = " KMGT"; 77 | 78 | static int 79 | can_output(void) 80 | { 81 | /* 82 | * Minix now has tcgetpgrp but is currently unsupported and returns 83 | * -1 here, but output works so just force it for now. 84 | */ 85 | #if defined(HAVE_TCGETPGRP) && !defined(__minix) 86 | return (getpgrp() == tcgetpgrp(STDOUT_FILENO)); 87 | #else 88 | return 1; 89 | #endif 90 | } 91 | 92 | static void 93 | format_rate(char *buf, int size, off_t bytes) 94 | { 95 | int i; 96 | 97 | bytes *= 100; 98 | for (i = 0; bytes >= 100*1000 && unit[i] != 'T'; i++) 99 | bytes = (bytes + 512) / 1024; 100 | if (i == 0) { 101 | i++; 102 | bytes = (bytes + 512) / 1024; 103 | } 104 | snprintf(buf, size, "%3lld.%1lld%c%s", 105 | (long long) (bytes + 5) / 100, 106 | (long long) (bytes + 5) / 10 % 10, 107 | unit[i], 108 | i ? "B" : " "); 109 | } 110 | 111 | static void 112 | format_size(char *buf, int size, off_t bytes) 113 | { 114 | int i; 115 | 116 | for (i = 0; bytes >= 10000 && unit[i] != 'T'; i++) 117 | bytes = (bytes + 512) / 1024; 118 | snprintf(buf, size, "%4lld%c%s", 119 | (long long) bytes, 120 | unit[i], 121 | i ? "B" : " "); 122 | } 123 | 124 | void 125 | refresh_progress_meter(void) 126 | { 127 | char buf[MAX_WINSIZE + 1]; 128 | time_t now; 129 | off_t transferred; 130 | double elapsed; 131 | int percent; 132 | off_t bytes_left; 133 | int cur_speed; 134 | int hours, minutes, seconds; 135 | int i, len; 136 | int file_len; 137 | 138 | transferred = *counter - (cur_pos ? cur_pos : start_pos); 139 | cur_pos = *counter; 140 | now = time(NULL); 141 | bytes_left = end_pos - cur_pos; 142 | 143 | if (bytes_left > 0) 144 | elapsed = now - last_update; 145 | else { 146 | elapsed = now - start; 147 | /* Calculate true total speed when done */ 148 | transferred = end_pos - start_pos; 149 | bytes_per_second = 0; 150 | } 151 | 152 | /* calculate speed */ 153 | if (elapsed != 0) 154 | cur_speed = (transferred / elapsed); 155 | else 156 | cur_speed = transferred; 157 | 158 | #define AGE_FACTOR 0.9 159 | if (bytes_per_second != 0) { 160 | bytes_per_second = (bytes_per_second * AGE_FACTOR) + 161 | (cur_speed * (1.0 - AGE_FACTOR)); 162 | } else 163 | bytes_per_second = cur_speed; 164 | 165 | /* filename */ 166 | buf[0] = '\0'; 167 | file_len = win_size - 35; 168 | if (file_len > 0) { 169 | len = snprintf(buf, file_len + 1, "\r%s", file); 170 | if (len < 0) 171 | len = 0; 172 | if (len >= file_len + 1) 173 | len = file_len; 174 | for (i = len; i < file_len; i++) 175 | buf[i] = ' '; 176 | buf[file_len] = '\0'; 177 | } 178 | 179 | /* percent of transfer done */ 180 | if (end_pos == 0 || cur_pos == end_pos) 181 | percent = 100; 182 | else 183 | percent = ((float)cur_pos / end_pos) * 100; 184 | snprintf(buf + strlen(buf), win_size - strlen(buf), 185 | " %3d%% ", percent); 186 | 187 | /* amount transferred */ 188 | format_size(buf + strlen(buf), win_size - strlen(buf), 189 | cur_pos); 190 | strlcat(buf, " ", win_size); 191 | 192 | /* bandwidth usage */ 193 | format_rate(buf + strlen(buf), win_size - strlen(buf), 194 | (off_t)bytes_per_second); 195 | strlcat(buf, "/s ", win_size); 196 | 197 | /* ETA */ 198 | if (!transferred) 199 | stalled += elapsed; 200 | else 201 | stalled = 0; 202 | 203 | if (stalled >= STALL_TIME) 204 | strlcat(buf, "- stalled -", win_size); 205 | else if (bytes_per_second == 0 && bytes_left) 206 | strlcat(buf, " --:-- ETA", win_size); 207 | else { 208 | if (bytes_left > 0) 209 | seconds = bytes_left / bytes_per_second; 210 | else 211 | seconds = elapsed; 212 | 213 | hours = seconds / 3600; 214 | seconds -= hours * 3600; 215 | minutes = seconds / 60; 216 | seconds -= minutes * 60; 217 | 218 | if (hours != 0) 219 | snprintf(buf + strlen(buf), win_size - strlen(buf), 220 | "%d:%02d:%02d", hours, minutes, seconds); 221 | else 222 | snprintf(buf + strlen(buf), win_size - strlen(buf), 223 | " %02d:%02d", minutes, seconds); 224 | 225 | if (bytes_left > 0) 226 | strlcat(buf, " ETA", win_size); 227 | else 228 | strlcat(buf, " ", win_size); 229 | } 230 | 231 | /* Silly workaround for -Werror=unused-result */ 232 | if (write(STDOUT_FILENO, buf, win_size - 1) <= 0) {} 233 | last_update = now; 234 | } 235 | 236 | /*ARGSUSED*/ 237 | static void 238 | update_progress_meter(int ignore) 239 | { 240 | int save_errno; 241 | 242 | save_errno = errno; 243 | 244 | if (win_resized) { 245 | setscreensize(); 246 | win_resized = 0; 247 | } 248 | if (can_output()) 249 | refresh_progress_meter(); 250 | 251 | signal(SIGALRM, update_progress_meter); 252 | alarm(UPDATE_INTERVAL); 253 | errno = save_errno; 254 | } 255 | 256 | void 257 | start_progress_meter(const char *f, off_t filesize, off_t *ctr) 258 | { 259 | start = last_update = time(NULL); 260 | file = f; 261 | start_pos = *ctr; 262 | end_pos = filesize; 263 | cur_pos = 0; 264 | counter = ctr; 265 | stalled = 0; 266 | bytes_per_second = 0; 267 | 268 | setscreensize(); 269 | if (can_output()) 270 | refresh_progress_meter(); 271 | 272 | signal(SIGALRM, update_progress_meter); 273 | signal(SIGWINCH, sig_winch); 274 | alarm(UPDATE_INTERVAL); 275 | } 276 | 277 | void 278 | stop_progress_meter(void) 279 | { 280 | alarm(0); 281 | 282 | if (!can_output()) 283 | return; 284 | 285 | /* Ensure we complete the progress */ 286 | if (cur_pos != end_pos) 287 | refresh_progress_meter(); 288 | 289 | /* Silly workaround for -Werror=unused-result */ 290 | if (write(STDOUT_FILENO, "\n", 1) <= 0) {} 291 | } 292 | 293 | /*ARGSUSED*/ 294 | static void 295 | sig_winch(int sig) 296 | { 297 | win_resized = 1; 298 | } 299 | 300 | static void 301 | setscreensize(void) 302 | { 303 | struct winsize winsize; 304 | 305 | if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &winsize) != -1 && 306 | winsize.ws_col != 0) { 307 | if (winsize.ws_col > MAX_WINSIZE) 308 | win_size = MAX_WINSIZE; 309 | else 310 | win_size = winsize.ws_col; 311 | } else 312 | win_size = DEFAULT_WINSIZE; 313 | win_size += 1; /* trailing \0 */ 314 | } 315 | -------------------------------------------------------------------------------- /external/progressmeter.h: -------------------------------------------------------------------------------- 1 | /* NetBSD: progressmeter.h,v 1.2 2006/09/28 21:22:14 christos Exp */ 2 | /* OpenBSD: progressmeter.h,v 1.2 2006/03/25 22:22:43 djm Exp */ 3 | /* 4 | * Copyright (c) 2002 Nils Nordman. 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 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | #include "config.h" 28 | 29 | #if HAVE_NBCOMPAT_H 30 | #include 31 | #endif 32 | 33 | #if defined(HAVE_SYS_TERMIOS_H) && !defined(__FreeBSD__) 34 | #include 35 | #elif HAVE_TERMIOS_H 36 | #include 37 | #endif 38 | 39 | void start_progress_meter(const char *, off_t, off_t *); 40 | void stop_progress_meter(void); 41 | -------------------------------------------------------------------------------- /external/var.c: -------------------------------------------------------------------------------- 1 | /* NetBSD: var.c,v 1.10 2013/09/12 07:28:28 wiz Exp */ 2 | 3 | /*- 4 | * Copyright (c) 2005, 2008 The NetBSD Foundation, Inc. 5 | * All rights reserved. 6 | * 7 | * This code is derived from software contributed to The NetBSD Foundation 8 | * by Dieter Baron, Thomas Klausner, Johnny Lam, and Joerg Sonnenberger. 9 | * 10 | * Redistribution and use in source and binary forms, with or without 11 | * modification, are permitted provided that the following conditions 12 | * are met: 13 | * 1. Redistributions of source code must retain the above copyright 14 | * notice, this list of conditions and the following disclaimer. 15 | * 2. Redistributions in binary form must reproduce the above copyright 16 | * notice, this list of conditions and the following disclaimer in the 17 | * documentation and/or other materials provided with the distribution. 18 | * 3. Neither the name of The NetBSD Foundation nor the names of its 19 | * contributors may be used to endorse or promote products derived 20 | * from this software without specific prior written permission. 21 | * 22 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 23 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 24 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 25 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 26 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 29 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 30 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 | * POSSIBILITY OF SUCH DAMAGE. 33 | */ 34 | 35 | #include "lib.h" 36 | 37 | static const char *var_cmp(const char *, size_t, const char *, size_t); 38 | static void var_print(FILE *, const char *, const char *); 39 | 40 | /* 41 | * Copy the specified variables from the file fname to stdout. 42 | */ 43 | int 44 | var_copy_list(const char *buf, const char **variables) 45 | { 46 | const char *eol, *next; 47 | size_t len; 48 | int i; 49 | 50 | for (; *buf; buf = next) { 51 | if ((eol = strchr(buf, '\n')) != NULL) { 52 | next = eol + 1; 53 | len = eol - buf; 54 | } else { 55 | len = strlen(buf); 56 | next = buf + len; 57 | } 58 | 59 | for (i=0; variables[i]; i++) { 60 | if (var_cmp(buf, len, variables[i], 61 | strlen(variables[i])) != NULL) { 62 | printf("%.*s\n", (int)len, buf); 63 | break; 64 | } 65 | } 66 | } 67 | return 0; 68 | } 69 | 70 | /* 71 | * Print the value of variable from the file fname to stdout. 72 | */ 73 | char * 74 | var_get(const char *fname, const char *variable) 75 | { 76 | FILE *fp; 77 | char *line; 78 | size_t len; 79 | size_t varlen; 80 | char *value; 81 | size_t valuelen; 82 | size_t thislen; 83 | const char *p; 84 | 85 | varlen = strlen(variable); 86 | if (varlen == 0) 87 | return NULL; 88 | 89 | fp = fopen(fname, "r"); 90 | if (!fp) { 91 | if (errno != ENOENT) 92 | warn("var_get: can't open '%s' for reading", fname); 93 | return NULL; 94 | } 95 | 96 | value = NULL; 97 | valuelen = 0; 98 | 99 | while ((line = fgetln(fp, &len)) != (char *) NULL) { 100 | if (line[len - 1] == '\n') 101 | --len; 102 | if ((p=var_cmp(line, len, variable, varlen)) == NULL) 103 | continue; 104 | 105 | thislen = line+len - p; 106 | if (value) { 107 | value = xrealloc(value, valuelen+thislen+2); 108 | value[valuelen++] = '\n'; 109 | } 110 | else { 111 | value = xmalloc(thislen+1); 112 | } 113 | sprintf(value+valuelen, "%.*s", (int)thislen, p); 114 | valuelen += thislen; 115 | } 116 | (void) fclose(fp); 117 | return value; 118 | } 119 | 120 | /* 121 | * Print the value of variable from the memory buffer to stdout. 122 | */ 123 | char * 124 | var_get_memory(const char *buf, const char *variable) 125 | { 126 | const char *eol, *next, *data; 127 | size_t len, varlen, thislen, valuelen; 128 | char *value; 129 | 130 | varlen = strlen(variable); 131 | if (varlen == 0) 132 | return NULL; 133 | 134 | value = NULL; 135 | valuelen = 0; 136 | 137 | for (; buf && *buf; buf = next) { 138 | if ((eol = strchr(buf, '\n')) != NULL) { 139 | next = eol + 1; 140 | len = eol - buf; 141 | } else { 142 | next = eol; 143 | len = strlen(buf); 144 | } 145 | if ((data = var_cmp(buf, len, variable, varlen)) == NULL) 146 | continue; 147 | 148 | thislen = buf + len - data; 149 | if (value) { 150 | value = xrealloc(value, valuelen+thislen+2); 151 | value[valuelen++] = '\n'; 152 | } 153 | else { 154 | value = xmalloc(thislen+1); 155 | } 156 | sprintf(value + valuelen, "%.*s", (int)thislen, data); 157 | valuelen += thislen; 158 | } 159 | return value; 160 | } 161 | 162 | /* 163 | * Add given variable with given value to file, overwriting any 164 | * previous occurrence. 165 | */ 166 | int 167 | var_set(const char *fname, const char *variable, const char *value) 168 | { 169 | FILE *fp; 170 | FILE *fout; 171 | char *tmpname; 172 | int fd; 173 | char *line; 174 | size_t len; 175 | size_t varlen; 176 | Boolean done; 177 | struct stat st; 178 | 179 | varlen = strlen(variable); 180 | if (varlen == 0) 181 | return 0; 182 | 183 | fp = fopen(fname, "r"); 184 | if (fp == NULL) { 185 | if (errno != ENOENT) { 186 | warn("var_set: can't open '%s' for reading", fname); 187 | return -1; 188 | } 189 | if (value == NULL) 190 | return 0; /* Nothing to do */ 191 | } 192 | 193 | tmpname = xasprintf("%s.XXXXXX", fname); 194 | if ((fd = mkstemp(tmpname)) < 0) { 195 | free(tmpname); 196 | if (fp != NULL) 197 | fclose(fp); 198 | warn("var_set: can't open temp file for '%s' for writing", 199 | fname); 200 | return -1; 201 | } 202 | if (chmod(tmpname, 0644) < 0) { 203 | close(fd); 204 | if (fp != NULL) 205 | fclose(fp); 206 | free(tmpname); 207 | warn("var_set: can't set permissions for temp file for '%s'", 208 | fname); 209 | return -1; 210 | } 211 | if ((fout=fdopen(fd, "w")) == NULL) { 212 | close(fd); 213 | remove(tmpname); 214 | free(tmpname); 215 | if (fp != NULL) 216 | fclose(fp); 217 | warn("var_set: can't open temp file for '%s' for writing", 218 | fname); 219 | return -1; 220 | } 221 | 222 | done = FALSE; 223 | 224 | if (fp) { 225 | while ((line = fgetln(fp, &len)) != (char *) NULL) { 226 | if (var_cmp(line, len, variable, varlen) == NULL) 227 | fprintf(fout, "%.*s", (int)len, line); 228 | else { 229 | if (!done && value) { 230 | var_print(fout, variable, value); 231 | done = TRUE; 232 | } 233 | } 234 | } 235 | (void) fclose(fp); 236 | } 237 | 238 | if (!done && value) 239 | var_print(fout, variable, value); 240 | 241 | if (fclose(fout) < 0) { 242 | free(tmpname); 243 | warn("var_set: write error for '%s'", fname); 244 | return -1; 245 | } 246 | 247 | if (stat(tmpname, &st) < 0) { 248 | free(tmpname); 249 | warn("var_set: cannot stat tempfile for '%s'", fname); 250 | return -1; 251 | } 252 | 253 | if (st.st_size == 0) { 254 | if (remove(tmpname) < 0) { 255 | free(tmpname); 256 | warn("var_set: cannot remove tempfile for '%s'", 257 | fname); 258 | return -1; 259 | } 260 | free(tmpname); 261 | if (remove(fname) < 0) { 262 | warn("var_set: cannot remove '%s'", fname); 263 | return -1; 264 | } 265 | return 0; 266 | } 267 | 268 | if (rename(tmpname, fname) < 0) { 269 | free(tmpname); 270 | warn("var_set: cannot move tempfile to '%s'", fname); 271 | return -1; 272 | } 273 | free(tmpname); 274 | return 0; 275 | } 276 | 277 | /* 278 | * Check if line contains variable var, return pointer to its value or NULL. 279 | */ 280 | static const char * 281 | var_cmp(const char *line, size_t linelen, const char *var, size_t varlen) 282 | { 283 | /* 284 | * We expect lines to look like one of the following 285 | * forms: 286 | * VAR=value 287 | * VAR= value 288 | * We print out the value of VAR, or nothing if it 289 | * doesn't exist. 290 | */ 291 | if (linelen < varlen+1) 292 | return NULL; 293 | if (strncmp(var, line, varlen) != 0) 294 | return NULL; 295 | 296 | line += varlen; 297 | if (*line != '=') 298 | return NULL; 299 | 300 | ++line; 301 | linelen -= varlen+1; 302 | if (linelen > 0 && *line == ' ') 303 | ++line; 304 | return line; 305 | } 306 | 307 | /* 308 | * Print given variable with value to file f. 309 | */ 310 | static void 311 | var_print(FILE *f, const char *variable, const char *value) 312 | { 313 | const char *p; 314 | 315 | while ((p=strchr(value, '\n')) != NULL) { 316 | if (p != value) 317 | fprintf(f, "%s=%.*s\n", variable, (int)(p-value), value); 318 | value = p+1; 319 | } 320 | 321 | if (*value) 322 | fprintf(f, "%s=%s\n", variable, value); 323 | } 324 | -------------------------------------------------------------------------------- /external/xwrapper.c: -------------------------------------------------------------------------------- 1 | /* NetBSD: xwrapper.c,v 1.2 2009/02/02 12:35:01 joerg Exp */ 2 | 3 | /*- 4 | * Copyright (c) 2008 Joerg Sonnenberger . 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in 15 | * the documentation and/or other materials provided with the 16 | * distribution. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 21 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 22 | * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 23 | * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 26 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 28 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 | * SUCH DAMAGE. 30 | */ 31 | 32 | #include "lib.h" 33 | 34 | char * 35 | xasprintf(const char *fmt, ...) 36 | { 37 | va_list ap; 38 | char *buf; 39 | 40 | va_start(ap, fmt); 41 | if (vasprintf(&buf, fmt, ap) == -1) 42 | err(1, "asprintf failed"); 43 | va_end(ap); 44 | return buf; 45 | } 46 | 47 | void * 48 | xmalloc(size_t len) 49 | { 50 | void *ptr; 51 | 52 | if ((ptr = malloc(len)) == NULL) 53 | err(1, "malloc failed"); 54 | return ptr; 55 | } 56 | 57 | void * 58 | xcalloc(size_t len, size_t n) 59 | { 60 | void *ptr; 61 | 62 | if ((ptr = calloc(len, n)) == NULL) 63 | err(1, "calloc failed"); 64 | return ptr; 65 | } 66 | 67 | void * 68 | xrealloc(void *buf, size_t len) 69 | { 70 | void *ptr; 71 | 72 | if ((ptr = realloc(buf, len)) == NULL) 73 | err(1, "realloc failed"); 74 | return ptr; 75 | } 76 | 77 | char * 78 | xstrdup(const char *str) 79 | { 80 | char *buf; 81 | 82 | if ((buf = strdup(str)) == NULL) 83 | err(1, "strdup failed"); 84 | return buf; 85 | } 86 | -------------------------------------------------------------------------------- /fsops.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2015 The NetBSD Foundation, Inc. 3 | * All rights reserved. 4 | * 5 | * This code is derived from software contributed to The NetBSD Foundation 6 | * by Emile "iMil" Heitor . 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 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 | * SUCH DAMAGE. 28 | */ 29 | 30 | #include 31 | #if _FILE_OFFSET_BITS == 32 32 | #undef _FILE_OFFSET_BITS 33 | #define _FILE_OFFSET_BITS 64 /* needed for large filesystems on sunos */ 34 | #endif 35 | #include "pkgin.h" 36 | #include 37 | 38 | /* Variable options for the repositories file */ 39 | static const struct VarParam { 40 | const char *opt; 41 | char *(*func)(void); 42 | } var[] = { 43 | { "$arch", getosarch }, 44 | { "$osrelease", getosrelease }, 45 | { NULL, NULL } 46 | }; 47 | 48 | uint64_t 49 | fs_room(const char *dir) 50 | { 51 | struct statvfs fsbuf; 52 | 53 | if (statvfs(dir, &fsbuf) < 0) 54 | err(EXIT_FAILURE, "Can't statvfs() `%s'", dir); 55 | 56 | return fsbuf.f_bavail * fsbuf.f_frsize; 57 | } 58 | 59 | void 60 | clean_cache(void) 61 | { 62 | DIR *dp; 63 | struct dirent *ep; 64 | char pkgpath[BUFSIZ + 1]; 65 | 66 | if ((dp = opendir(pkgin_cache)) == NULL) 67 | err(EXIT_FAILURE, "couldn't open %s", pkgin_cache); 68 | 69 | while ((ep = readdir(dp)) != NULL) 70 | if (ep->d_name[0] != '.') { 71 | snprintf(pkgpath, sizeof(pkgpath), "%s/%s", 72 | pkgin_cache, ep->d_name); 73 | if (unlink(pkgpath) < 0) 74 | err(EXIT_FAILURE, 75 | "could not delete %s", pkgpath); 76 | } 77 | closedir(dp); 78 | } 79 | 80 | char * 81 | read_repos(void) 82 | { 83 | FILE *fp; 84 | char *tmp, *b, *repos = NULL, buf[BUFSIZ]; 85 | size_t curlen = 0, repolen = 0; 86 | const struct VarParam *vp; 87 | 88 | if ((fp = fopen(PKGIN_CONF"/"REPOS_FILE, "r")) == NULL) 89 | return NULL; 90 | 91 | while (!feof(fp) && !ferror(fp)) { 92 | memset(buf, 0, BUFSIZ); 93 | 94 | if (fgets(buf, BUFSIZ, fp) == NULL) 95 | continue; 96 | 97 | if (strncmp(buf, "ftp://", 6) != 0 && 98 | strncmp(buf, "http://", 7) != 0 && 99 | strncmp(buf, "https://", 8) != 0 && 100 | strncmp(buf, "file://", 7) != 0) 101 | continue; 102 | 103 | /* 104 | * Try to replace all the ocurrences with the proper 105 | * system values. 106 | */ 107 | for (vp = var; vp->func != NULL; vp++) { 108 | if (strstr(buf, vp->opt) != NULL) { 109 | tmp = vp->func(); 110 | if (tmp == NULL) { 111 | warn(MSG_TRANS_FAILED, vp->opt); 112 | continue; 113 | } 114 | if ((b = strreplace(buf, vp->opt, tmp)) != NULL) 115 | strncpy(buf, b, BUFSIZ - 1); 116 | else 117 | warn(MSG_INVALID_REPOS, buf); 118 | 119 | XFREE(tmp); 120 | XFREE(b); 121 | } 122 | } 123 | 124 | curlen = trimcr(buf) + 2; /* ' ' + '\0' */ 125 | repolen += curlen; 126 | 127 | repos = xrealloc(repos, repolen * sizeof(char)); 128 | 129 | if (repolen > curlen) /* more than one repo */ { 130 | /* add a space character */ 131 | curlen = strlen(repos); 132 | repos[curlen] = ' '; 133 | repos[curlen + 1] = '\0'; 134 | } else 135 | /* 1st entry */ 136 | memset(repos, 0, curlen); 137 | 138 | strcat(repos, buf); 139 | } 140 | 141 | fclose(fp); 142 | 143 | return repos; 144 | } 145 | -------------------------------------------------------------------------------- /htdocs/gfx/pkgin-flashy-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NetBSDfr/pkgin/0f9268a20d8b53bd41672f19f46629ec5f1a6ff0/htdocs/gfx/pkgin-flashy-icon.png -------------------------------------------------------------------------------- /htdocs/gfx/pkgin-icon-new.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NetBSDfr/pkgin/0f9268a20d8b53bd41672f19f46629ec5f1a6ff0/htdocs/gfx/pkgin-icon-new.png -------------------------------------------------------------------------------- /htdocs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | pkgin, a binary package manager for pkgsrc 6 | 7 | 8 | 9 | 10 |
11 | 12 |

pkgin, a binary package manager for pkgsrc

13 | 14 |

15 | pkgin is aimed at being an apt / yum like tool for managing pkgsrc binary packages. It relies on pkg_summary(5) for installation, removal and upgrade of packages and associated dependencies, using a remote repository. 16 |

17 | 18 |

Quickstart

19 | 33 | 34 |

Rationale

35 | 36 |

37 | Many so-called GNU/Linux distributions provide a convenient way of searching, installing and upgrading software by using binary archives found on "repositories". NetBSD, and more widely, all operating systems relying on pkgsrc have tools like pkg_add and pkg_delete, but those are unable to correctly handle binary upgrades, and sometimes even installation itself. 38 |

39 |

40 | This is the purpose of pkgin, to provide the user a convenient way to handle binary packages, using the same working mechanisms as tools like apt-get. 41 |

42 | 43 |

Disclaimer

44 | 45 |

46 | As pkgin CVS code may change quite deeply, please do not forget to look at the CHANGES file if you chose to track development version. 47 |

48 | 49 |

Prerequisites

50 | 51 |

52 | pkgin is developed using the C language. It uses sqlite3 as a package database backend, in order to provide good speed on older architectures. 53 |

54 |

If you wish to build pkgin from sources, the following dependencies must be met 55 |

    56 |
  • databases/sqlite3
  • 57 |
  • pkgtools/libnbcompat (yes, even for NetBSD)
  • 58 |
  • net/libfetch
  • 59 |
  • archivers/libarchive
  • 60 |
61 | Since NetBSD 6.0, all of those are provided as part of the base system, except for libnbcompat. 62 |

63 |

64 | Pkgin is available via CVS, pkgsrc-wip and is available in pkgsrc as pkgtools/pkgin. 65 |

66 | 67 |

68 | While installing via pkgsrc is the preferred method, you may want to track CVS version to help improving pkgin's quality. To check it out, use the following commands: 69 |

70 |
$ cvs -d:pserver:anonymous@cvs.pkgin.net:/cvsroot/pkgin login
 71 | passwd: [enter]
 72 | $ cvs -z3 -d:pserver:anonymous@cvs.pkgin.net:/cvsroot/pkgin co -P pkgin
73 |

Invoke the configure script, for example:

74 |
$ ./configure --prefix=/usr/pkg --with-libraries=/usr/pkg/lib --with-includes=/usr/pkg/include
75 |

76 | And finally build the binary: 77 |

78 |
$ make
79 | 80 |

pkgin is ready to run !

81 | 82 |

Usage

83 | 84 |

85 | First thing to do before using pkgin is to setup a repository in the ${PREFIX}/etc/pkgin/repositories.conf file : 86 |

87 |
$ echo ftp://ftp.fr.netbsd.org/pub/pkgsrc/packages/NetBSD/i386/5.0/All > /usr/pkg/etc/pkgin/repositories.conf
88 | 89 |

90 | Now you can build the initial database: 91 |

92 |
# pkgin update
93 | 94 |

This operation will download the pkg_summary(5) file from the repository and then populate the SQLite database.

95 | 96 |

Once this is completed, pkgin is fully functionnal.

97 | 98 |

The pkgin update command must be run regularly in order to keep the database synchronized with the repository.

99 | 100 |

Usage examples

101 | 102 |

List available packages:

103 |
# pkgin avail
104 | 105 |

List installed packages:

106 |
# pkgin list
107 | 108 |

Search for a regular expression in the database:

109 |
# pkgin search foo.*bar
110 | 111 |

Install a package and its dependencies:

112 |
# pkgin install foo
113 | 114 |

Install many packages and their dependencies:

115 |
# pkgin install foo bar baz
116 | 117 |

Install a package and its dependencies using a "glob" syntax (pkgin 0.5 and up):

118 |
# pkgin install 'foo<5.0'
119 | 120 |

Remove a package and its reverse dependencies:

121 |
# pkgin remove foo
122 | 123 |

Upgrade a package:

124 |
# pkgin install foo
125 | 126 |

Remove orphan dependencies:

127 |
# pkgin autoremove
128 | 129 |

Mark a package as "keepable", i.e. a package that probably has not been installed by pkgin but that is not an orphan dependency:

130 |
# pkgin keep foo
131 | 132 |

Mark a package as "non-keepable":

133 |
# pkgin unkeep foo
134 | 135 |

Upgrade all packages to the newest versions available in the repository:

136 |
# pkgin upgrade
137 | 138 |

Delete downloaded packages from the cache directory:

139 |
# pkgin clean
140 | 141 |

Show package direct dependencies:

142 |
# pkgin show-deps foo
143 | 144 |

Show package full dependency tree:

145 |
# pkgin show-full-deps foo
146 | 147 |

Show package reverse dependency tree (packages depending directly or indirectly):

148 |
# pkgin show-rev-deps foo
149 | 150 |

Assume "yes" for all questions:

151 |
# pkgin -y install foo
152 | 153 |

Export your keep-list (in pkg_chk(8) format, pkgin 0.5 and up):

154 |
# pkgin export > my-packages
155 | 156 |

Import a package list (in pkg_chk(8) format, pkgin 0.5 and up):

157 |
# pkgin import my-packages
158 | 159 |

Shows what a package provides (pkgin 0.5 and up):

160 |
# pkgin provides foo
161 | 162 |

Shows what a package requires (pkgin 0.5 and up):

163 |
# pkgin requires foo
164 | 165 |

Show packages belonging to category (pkgin 0.6 and up):

166 |
# pkgin show-category www
167 | 168 |

Show package's category (pkgin 0.6 and up):

169 |
# pkgin show-pkg-category foo
170 | 171 |

Show remote package's content (pkgin 0.6 and up):

172 |
# pkgin pkg-content foo
173 | 174 |

Show remote package's long-description (pkgin 0.6 and up):

175 |
# pkgin pkg-descr foo
176 | 177 |

Show remote package's build definitions (pkgin 0.6 and up):

178 |
# pkgin pkg-build-defs foo
179 | 180 |

Every command has a shortcut, pkgin -h will show them.

181 | 182 |

Platforms

183 | 184 |

185 | pkgin is known to work and have been tested under the following platforms : 186 |

    187 |
  • NetBSD {4,5,6, current}
  • 188 |
  • DragonFly BSD 2.0 to 3.0
  • 189 |
  • Solaris 10/SunOS 5.10
  • 190 |
  • Opensolaris/SunOS 5.11
  • 191 |
  • Debian GNU/Linux {5,6}
  • 192 |
  • Mac OS X 10.5 to 10.10
  • 193 |
  • MINIX 3.2.0 and 3.3.0
  • 194 |
195 |

196 | 197 |

Contact

198 | 199 |

200 | Please do not hesitate to contact me, either by mail at imil@NetBSD.org or iMil on the Libera.Chat IRC Network. 201 |

202 | 203 |

204 | 205 |

206 |
207 | 208 | 209 | 210 | -------------------------------------------------------------------------------- /install-sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # $NetBSD: install-sh.in,v 1.6 2012/01/11 13:07:31 hans Exp $ 4 | # This script now also installs multiple files, but might choke on installing 5 | # multiple files with spaces in the file names. 6 | # 7 | # install - install a program, script, or datafile 8 | # This comes from X11R5 (mit/util/scripts/install.sh). 9 | # 10 | # Copyright 1991 by the Massachusetts Institute of Technology 11 | # 12 | # Permission to use, copy, modify, distribute, and sell this software and its 13 | # documentation for any purpose is hereby granted without fee, provided that 14 | # the above copyright notice appear in all copies and that both that 15 | # copyright notice and this permission notice appear in supporting 16 | # documentation, and that the name of M.I.T. not be used in advertising or 17 | # publicity pertaining to distribution of the software without specific, 18 | # written prior permission. M.I.T. makes no representations about the 19 | # suitability of this software for any purpose. It is provided "as is" 20 | # without express or implied warranty. 21 | # 22 | # Calling this script install-sh is preferred over install.sh, to prevent 23 | # `make' implicit rules from creating a file called install from it 24 | # when there is no Makefile. 25 | # 26 | # This script is compatible with the BSD install script, but was written 27 | # from scratch. 28 | 29 | # set DOITPROG to echo to test this script 30 | 31 | # Don't use :- since 4.3BSD and earlier shells don't like it. 32 | doit="${DOITPROG-}" 33 | 34 | 35 | # put in absolute paths if you don't have them in your path; or use env. vars. 36 | 37 | awkprog="${AWKPROG-awk}" 38 | mvprog="${MVPROG-mv}" 39 | cpprog="${CPPROG-cp}" 40 | chmodprog="${CHMODPROG-chmod}" 41 | chownprog="${CHOWNPROG-chown}" 42 | chgrpprog="${CHGRPPROG-chgrp}" 43 | stripprog="${STRIPPROG-strip}" 44 | rmprog="${RMPROG-rm}" 45 | mkdirprog="${MKDIRPROG-mkdir}" 46 | 47 | instcmd="$cpprog" 48 | instflags="" 49 | pathcompchmodcmd="$chmodprog 755" 50 | chmodcmd="$chmodprog 755" 51 | chowncmd="" 52 | chgrpcmd="" 53 | stripcmd="" 54 | stripflags="" 55 | rmcmd="$rmprog -f" 56 | mvcmd="$mvprog" 57 | src="" 58 | msrc="" 59 | dst="" 60 | dir_arg="" 61 | suffix="" 62 | suffixfmt="" 63 | 64 | while [ x"$1" != x ]; do 65 | case $1 in 66 | -b) suffix=".old" 67 | shift 68 | continue;; 69 | 70 | -B) suffixfmt="$2" 71 | shift 72 | shift 73 | continue;; 74 | 75 | -c) instcmd="$cpprog" 76 | shift 77 | continue;; 78 | 79 | -d) dir_arg=true 80 | shift 81 | continue;; 82 | 83 | -m) chmodcmd="$chmodprog $2" 84 | shift 85 | shift 86 | continue;; 87 | 88 | -m*) 89 | chmodcmd="$chmodprog ${1#-m}" 90 | shift 91 | continue;; 92 | 93 | -o) chowncmd="$chownprog $2" 94 | shift 95 | shift 96 | continue;; 97 | 98 | -g) chgrpcmd="$chgrpprog $2" 99 | shift 100 | shift 101 | continue;; 102 | 103 | -s) stripcmd="$stripprog" 104 | shift 105 | continue;; 106 | 107 | -S) stripcmd="$stripprog" 108 | stripflags="-S $2 $stripflags" 109 | shift 110 | shift 111 | continue;; 112 | 113 | -p) instflags="-p" 114 | shift 115 | continue;; 116 | 117 | *) if [ x"$msrc" = x ] 118 | then 119 | msrc="$dst" 120 | else 121 | msrc="$msrc $dst" 122 | fi 123 | src="$dst" 124 | dst="$1" 125 | shift 126 | continue;; 127 | esac 128 | done 129 | 130 | if [ x"$dir_arg" = x ] 131 | then 132 | dstisfile="" 133 | if [ ! -d "$dst" ] 134 | then 135 | if [ x"$msrc" = x"$src" ] 136 | then 137 | dstisfile=true 138 | else 139 | echo "install: destination is not a directory" 140 | exit 1 141 | fi 142 | fi 143 | else 144 | msrc="$msrc $dst" 145 | fi 146 | 147 | if [ x"$msrc" = x ] 148 | then 149 | echo "install: no destination specified" 150 | exit 1 151 | fi 152 | 153 | for srcarg in $msrc; do 154 | 155 | if [ x"$dir_arg" != x ]; then 156 | 157 | dstarg="$srcarg" 158 | else 159 | dstarg="$dst" 160 | 161 | # Waiting for this to be detected by the "$instcmd $srcarg $dsttmp" command 162 | # might cause directories to be created, which would be especially bad 163 | # if $src (and thus $dsttmp) contains '*'. 164 | 165 | if [ -f "$srcarg" ] 166 | then 167 | doinst="$instcmd $instflags" 168 | elif [ -d "$srcarg" ] 169 | then 170 | echo "install: $srcarg: not a regular file" 171 | exit 1 172 | elif [ "$srcarg" = "/dev/null" ] 173 | then 174 | doinst="$cpprog" 175 | else 176 | echo "install: $srcarg does not exist" 177 | exit 1 178 | fi 179 | 180 | # If destination is a directory, append the input filename; if your system 181 | # does not like double slashes in filenames, you may need to add some logic 182 | 183 | if [ -d "$dstarg" ] 184 | then 185 | dstarg="$dstarg"/`basename "$srcarg"` 186 | fi 187 | fi 188 | 189 | ## this sed command emulates the dirname command 190 | dstdir=`echo "$dstarg" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` 191 | 192 | # Make sure that the destination directory exists. 193 | # this part is taken from Noah Friedman's mkinstalldirs script 194 | 195 | # Skip lots of stat calls in the usual case. 196 | if [ ! -d "$dstdir" ]; then 197 | defaultIFS=' 198 | ' 199 | IFS="${IFS-${defaultIFS}}" 200 | 201 | oIFS="${IFS}" 202 | # Some sh's can't handle IFS=/ for some reason. 203 | IFS='%' 204 | set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` 205 | IFS="${oIFS}" 206 | 207 | pathcomp='' 208 | 209 | while [ $# -ne 0 ] ; do 210 | pathcomp="${pathcomp}${1}" 211 | shift 212 | 213 | if [ ! -d "${pathcomp}" ] ; 214 | then 215 | $doit $mkdirprog "${pathcomp}" 216 | if [ x"$chowncmd" != x ]; then $doit $chowncmd "${pathcomp}"; else true ; fi && 217 | if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "${pathcomp}"; else true ; fi && 218 | if [ x"$pathcompchmodcmd" != x ]; then $doit $pathcompchmodcmd "${pathcomp}"; else true ; fi 219 | 220 | else 221 | true 222 | fi 223 | 224 | pathcomp="${pathcomp}/" 225 | done 226 | fi 227 | 228 | if [ x"$dir_arg" != x ] 229 | then 230 | if [ -d "$dstarg" ]; then 231 | true 232 | else 233 | $doit $mkdirprog "$dstarg" && 234 | 235 | if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dstarg"; else true ; fi && 236 | if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dstarg"; else true ; fi && 237 | if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dstarg"; else true ; fi 238 | fi 239 | else 240 | 241 | if [ x"$dstisfile" = x ] 242 | then 243 | file=$srcarg 244 | else 245 | file=$dst 246 | fi 247 | 248 | dstfile=`basename "$file"` 249 | dstfinal="$dstdir/$dstfile" 250 | 251 | # Make a temp file name in the proper directory. 252 | 253 | dsttmp=$dstdir/#inst.$$# 254 | 255 | # Make a backup file name in the proper directory. 256 | case x$suffixfmt in 257 | *%*) suffix=`echo x | 258 | $awkprog -v bname="$dstfinal" -v fmt="$suffixfmt" ' 259 | { cnt = 0; 260 | do { 261 | sfx = sprintf(fmt, cnt++); 262 | name = bname sfx; 263 | } while (system("test -f " name) == 0); 264 | print sfx; }' -`;; 265 | x) ;; 266 | *) suffix="$suffixfmt";; 267 | esac 268 | dstbackup="$dstfinal$suffix" 269 | 270 | # Move or copy the file name to the temp name 271 | 272 | $doit $doinst $srcarg "$dsttmp" && 273 | 274 | trap "rm -f ${dsttmp}" 0 && 275 | 276 | # and set any options; do chmod last to preserve setuid bits 277 | 278 | # If any of these fail, we abort the whole thing. If we want to 279 | # ignore errors from any of these, just make sure not to ignore 280 | # errors from the above "$doit $instcmd $src $dsttmp" command. 281 | 282 | if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else true;fi && 283 | if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else true;fi && 284 | if [ x"$stripcmd" != x ]; then $doit $stripcmd $stripflags "$dsttmp"; else true;fi && 285 | if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else true;fi && 286 | 287 | # Now rename the file to the real destination. 288 | 289 | if [ x"$suffix" != x ] && [ -f "$dstfinal" ] 290 | then 291 | $doit $mvcmd "$dstfinal" "$dstbackup" 292 | else 293 | $doit $rmcmd -f "$dstfinal" 294 | fi && 295 | $doit $mvcmd "$dsttmp" "$dstfinal" 296 | fi 297 | 298 | done && 299 | 300 | 301 | exit 0 302 | -------------------------------------------------------------------------------- /messages.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2015 The NetBSD Foundation, Inc. 3 | * All rights reserved. 4 | * 5 | * This code is derived from software contributed to The NetBSD Foundation 6 | * by Emile "iMil" Heitor . 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 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 | * SUCH DAMAGE. 28 | */ 29 | 30 | /* main.c */ 31 | #define MSG_MISSING_PKGNAME "missing package name" 32 | #define MSG_MISSING_FILENAME "missing file name" 33 | #define MSG_FULLDEPTREE "full dependency tree for %s\n" 34 | #define MSG_REVDEPTREE "local reverse dependency tree for %s\n" 35 | #define MSG_PKG_ARGS_INST "specify at least one package to install" 36 | #define MSG_PKG_ARGS_RM "specify at least one package to remove" 37 | #define MSG_PKG_ARGS_KEEP "specify at least one package to keep" 38 | #define MSG_PKG_ARGS_UNKEEP "specify at least one package to unkeep" 39 | #define MSG_MISSING_SRCH "missing search string" 40 | #define MSG_MISSING_CATEGORY "missing category" 41 | 42 | #define MSG_CHROOT_FAILED "Unable to chroot" 43 | #define MSG_CHDIR_FAILED "Unable to chroot" 44 | 45 | #define MSG_MISSING_PKG_REPOS \ 46 | PKGIN_CONF"/"REPOS_FILE" has no repositories or does not exist.\nNo PKG_REPOS variable to fallback to." 47 | #define MSG_CANT_OPEN_WRITE "Couldn't open %s for writing.\n" 48 | #define MSG_DONT_HAVE_RIGHTS "You don't have enough rights for this operation." 49 | 50 | /* actions.c */ 51 | #define MSG_NOT_REMOVING_PKG_INSTALL \ 52 | "pkg_install is a critical package and cannot be deleted\n" 53 | #define MSG_PKG_NO_REPO "%s has no associated repository" 54 | #define MSG_ERR_OPEN "error opening %s" 55 | #define MSG_REQT_NOT_PRESENT \ 56 | "%s, needed by %s is not present in this system.\n" 57 | #define MSG_REQT_NOT_PRESENT_DEPS \ 58 | "warning: %s is not present in this system nor package's dependencies\n" 59 | #define MSG_NOTHING_TO_DO "nothing to do.\n" 60 | #define MSG_REQT_MISSING "the following packages have unmet requirements: %s\n\n" 61 | #define MSG_NO_CACHE_SPACE "%s does not have enough space for download, (%s required but only %s are available)\n" 62 | #define MSG_NO_INSTALL_SPACE "%s does not have enough space for installation (%s required but only %s are available)\n" 63 | #define MSG_EMPTY_LOCAL_PKGLIST "empty local package list." 64 | #define MSG_PKG_NOT_INSTALLED "no such installed package %s\n" 65 | #define MSG_PKGS_TO_DELETE "%d packages to delete: \n%s\n" 66 | #define MSG_NO_PKGS_TO_DELETE "no packages to delete\n" 67 | #define MSG_EMPTY_KEEP_LIST "empty non-autoremovable package list" 68 | #define MSG_EMPTY_NOKEEP_LIST "empty autoremovable package list" 69 | #define MSG_EMPTY_AVAIL_PKGLIST "empty available packages list" 70 | #define MSG_PKG_INSTALL_LOGGING_TO "pkg_install error log can be found in %s\n" 71 | #define MSG_BAD_FILE_SIZE "warning: remote package %s has an invalid or missing FILE_SIZE\n" 72 | #define MSG_WARNS_ERRS "pkg_install warnings: %d, errors: %d\n" 73 | 74 | #define MSG_ONE_TO_REFRESH "1 package to refresh:\n%s\n\n" 75 | #define MSG_NUM_TO_REFRESH "%d packages to refresh:\n%s\n\n" 76 | #define MSG_ONE_TO_UPGRADE "1 package to upgrade:\n%s\n\n" 77 | #define MSG_NUM_TO_UPGRADE "%d packages to upgrade:\n%s\n\n" 78 | #define MSG_ONE_TO_INSTALL "1 package to install:\n%s\n\n" 79 | #define MSG_NUM_TO_INSTALL "%d packages to install:\n%s\n\n" 80 | #define MSG_ONE_TO_REMOVE "1 package to remove:\n%s\n\n" 81 | #define MSG_NUM_TO_REMOVE "%d packages to remove:\n%s\n\n" 82 | #define MSG_ONE_TO_SUPERSEDE "1 package to remove (superseded):\n%s\n\n" 83 | #define MSG_NUM_TO_SUPERSEDE "%d packages to remove (superseded):\n%s\n\n" 84 | #define MSG_ONE_TO_DOWNLOAD "1 package to download:\n%s\n\n" 85 | #define MSG_NUM_TO_DOWNLOAD "%d packages to download:\n%s\n\n" 86 | #define MSG_ALL_TO_ACTION "%d to remove, %d to refresh, " \ 87 | "%d to upgrade, %d to install\n" 88 | #define MSG_DOWNLOAD "%s to download\n" 89 | #define MSG_DOWNLOAD_USED "%s to download, " \ 90 | "%s of additional disk space will be used\n" 91 | #define MSG_DOWNLOAD_FREED "%s to download, " \ 92 | "%s of disk space will be freed up\n" 93 | #define MSG_PKGTOOLS_UPGRADED "Package tools were upgraded. Re-run " \ 94 | "\"pkgin upgrade\" to complete the upgrade.\n" 95 | 96 | /* depends.c */ 97 | #define MSG_DIRECT_DEPS_FOR "direct dependencies for %s\n" 98 | 99 | /* autoremove.c */ 100 | #define MSG_ALL_KEEP_PKGS "all packages are marked as \"keepable\"\n." 101 | #define MSG_AUTOREMOVE_PKGS "%d packages to be autoremoved:\n%s\n" 102 | #define MSG_MARKING_PKG_KEEP "marking %s as non auto-removable\n" 103 | #define MSG_UNMARKING_PKG_KEEP "marking %s as auto-removable\n" 104 | #define MSG_NO_ORPHAN_DEPS "no orphan dependencies found.\n" 105 | 106 | /* summary.c */ 107 | #define MSG_READING_LOCAL_SUMMARY "reading local summary...\n" 108 | #define MSG_CLEANING_DB_FROM_REPO "cleaning database from %s entries...\n" 109 | #define MSG_PROCESSING_LOCAL_SUMMARY "processing local summary...\n" 110 | #define MSG_DB_IS_UP_TO_DATE "database for %s is up-to-date\n" 111 | #define MSG_PROCESSING_REMOTE_SUMMARY "processing remote summary (%s)...\n" 112 | #define MSG_COULDNT_FETCH "Could not fetch %s: %s" 113 | #define MSG_ARCH_DONT_MATCH "\r\n/!\\ Warning /!\\ %s doesn't match your current architecture (%s)\nYou probably want to modify "PKGIN_CONF"/"REPOS_FILE".\nStill want to " 114 | #define MSG_COULD_NOT_GET_PKGNAME "Could not get package name from dependency: %s\n" 115 | 116 | /* impact.c */ 117 | #define MSG_PKG_NOT_AVAIL "%s is not available in the repository\n" 118 | #define MSG_PKG_NOT_PREFERRED "No %s package available that satisfies preferred match %s\n" 119 | 120 | /* pkglist.c */ 121 | #define MSG_IS_INSTALLED_CODE "\n=: package is installed and up-to-date\n<: package is installed but newer version is available\n>: installed package has a greater version than available package\n" 122 | #define MSG_NO_SEARCH_RESULTS "No results found for %s\n" 123 | #define MSG_EMPTY_LIST "Requested list is empty.\n" 124 | #define MSG_NO_CATEGORIES "No categories found.\n" 125 | 126 | /* fsops.c */ 127 | #define MSG_TRANS_FAILED "Failed to translate %s in repository config file" 128 | #define MSG_INVALID_REPOS "Invalid repository: %s" 129 | 130 | /* selection.c */ 131 | #define MSG_EMPTY_IMPORT_LIST "Empty import list." 132 | 133 | /* pkg_check.c */ 134 | #define MSG_NO_PROV_REQ "No shared libraries %s by %s.\n" 135 | #define MSG_FILES_PROV_REQ "Shared libraries %s by %s:\n" 136 | -------------------------------------------------------------------------------- /missing: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # Common wrapper for a few potentially missing GNU programs. 3 | 4 | scriptversion=2018-03-07.03; # UTC 5 | 6 | # Copyright (C) 1996-2021 Free Software Foundation, Inc. 7 | # Originally written by Fran,cois Pinard , 1996. 8 | 9 | # This program is free software; you can redistribute it and/or modify 10 | # it under the terms of the GNU General Public License as published by 11 | # the Free Software Foundation; either version 2, or (at your option) 12 | # any later version. 13 | 14 | # This program is distributed in the hope that it will be useful, 15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | # GNU General Public License for more details. 18 | 19 | # You should have received a copy of the GNU General Public License 20 | # along with this program. If not, see . 21 | 22 | # As a special exception to the GNU General Public License, if you 23 | # distribute this file as part of a program that contains a 24 | # configuration script generated by Autoconf, you may include it under 25 | # the same distribution terms that you use for the rest of that program. 26 | 27 | if test $# -eq 0; then 28 | echo 1>&2 "Try '$0 --help' for more information" 29 | exit 1 30 | fi 31 | 32 | case $1 in 33 | 34 | --is-lightweight) 35 | # Used by our autoconf macros to check whether the available missing 36 | # script is modern enough. 37 | exit 0 38 | ;; 39 | 40 | --run) 41 | # Back-compat with the calling convention used by older automake. 42 | shift 43 | ;; 44 | 45 | -h|--h|--he|--hel|--help) 46 | echo "\ 47 | $0 [OPTION]... PROGRAM [ARGUMENT]... 48 | 49 | Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due 50 | to PROGRAM being missing or too old. 51 | 52 | Options: 53 | -h, --help display this help and exit 54 | -v, --version output version information and exit 55 | 56 | Supported PROGRAM values: 57 | aclocal autoconf autoheader autom4te automake makeinfo 58 | bison yacc flex lex help2man 59 | 60 | Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and 61 | 'g' are ignored when checking the name. 62 | 63 | Send bug reports to ." 64 | exit $? 65 | ;; 66 | 67 | -v|--v|--ve|--ver|--vers|--versi|--versio|--version) 68 | echo "missing $scriptversion (GNU Automake)" 69 | exit $? 70 | ;; 71 | 72 | -*) 73 | echo 1>&2 "$0: unknown '$1' option" 74 | echo 1>&2 "Try '$0 --help' for more information" 75 | exit 1 76 | ;; 77 | 78 | esac 79 | 80 | # Run the given program, remember its exit status. 81 | "$@"; st=$? 82 | 83 | # If it succeeded, we are done. 84 | test $st -eq 0 && exit 0 85 | 86 | # Also exit now if we it failed (or wasn't found), and '--version' was 87 | # passed; such an option is passed most likely to detect whether the 88 | # program is present and works. 89 | case $2 in --version|--help) exit $st;; esac 90 | 91 | # Exit code 63 means version mismatch. This often happens when the user 92 | # tries to use an ancient version of a tool on a file that requires a 93 | # minimum version. 94 | if test $st -eq 63; then 95 | msg="probably too old" 96 | elif test $st -eq 127; then 97 | # Program was missing. 98 | msg="missing on your system" 99 | else 100 | # Program was found and executed, but failed. Give up. 101 | exit $st 102 | fi 103 | 104 | perl_URL=https://www.perl.org/ 105 | flex_URL=https://github.com/westes/flex 106 | gnu_software_URL=https://www.gnu.org/software 107 | 108 | program_details () 109 | { 110 | case $1 in 111 | aclocal|automake) 112 | echo "The '$1' program is part of the GNU Automake package:" 113 | echo "<$gnu_software_URL/automake>" 114 | echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" 115 | echo "<$gnu_software_URL/autoconf>" 116 | echo "<$gnu_software_URL/m4/>" 117 | echo "<$perl_URL>" 118 | ;; 119 | autoconf|autom4te|autoheader) 120 | echo "The '$1' program is part of the GNU Autoconf package:" 121 | echo "<$gnu_software_URL/autoconf/>" 122 | echo "It also requires GNU m4 and Perl in order to run:" 123 | echo "<$gnu_software_URL/m4/>" 124 | echo "<$perl_URL>" 125 | ;; 126 | esac 127 | } 128 | 129 | give_advice () 130 | { 131 | # Normalize program name to check for. 132 | normalized_program=`echo "$1" | sed ' 133 | s/^gnu-//; t 134 | s/^gnu//; t 135 | s/^g//; t'` 136 | 137 | printf '%s\n' "'$1' is $msg." 138 | 139 | configure_deps="'configure.ac' or m4 files included by 'configure.ac'" 140 | case $normalized_program in 141 | autoconf*) 142 | echo "You should only need it if you modified 'configure.ac'," 143 | echo "or m4 files included by it." 144 | program_details 'autoconf' 145 | ;; 146 | autoheader*) 147 | echo "You should only need it if you modified 'acconfig.h' or" 148 | echo "$configure_deps." 149 | program_details 'autoheader' 150 | ;; 151 | automake*) 152 | echo "You should only need it if you modified 'Makefile.am' or" 153 | echo "$configure_deps." 154 | program_details 'automake' 155 | ;; 156 | aclocal*) 157 | echo "You should only need it if you modified 'acinclude.m4' or" 158 | echo "$configure_deps." 159 | program_details 'aclocal' 160 | ;; 161 | autom4te*) 162 | echo "You might have modified some maintainer files that require" 163 | echo "the 'autom4te' program to be rebuilt." 164 | program_details 'autom4te' 165 | ;; 166 | bison*|yacc*) 167 | echo "You should only need it if you modified a '.y' file." 168 | echo "You may want to install the GNU Bison package:" 169 | echo "<$gnu_software_URL/bison/>" 170 | ;; 171 | lex*|flex*) 172 | echo "You should only need it if you modified a '.l' file." 173 | echo "You may want to install the Fast Lexical Analyzer package:" 174 | echo "<$flex_URL>" 175 | ;; 176 | help2man*) 177 | echo "You should only need it if you modified a dependency" \ 178 | "of a man page." 179 | echo "You may want to install the GNU Help2man package:" 180 | echo "<$gnu_software_URL/help2man/>" 181 | ;; 182 | makeinfo*) 183 | echo "You should only need it if you modified a '.texi' file, or" 184 | echo "any other file indirectly affecting the aspect of the manual." 185 | echo "You might want to install the Texinfo package:" 186 | echo "<$gnu_software_URL/texinfo/>" 187 | echo "The spurious makeinfo call might also be the consequence of" 188 | echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" 189 | echo "want to install GNU make:" 190 | echo "<$gnu_software_URL/make/>" 191 | ;; 192 | *) 193 | echo "You might have modified some files without having the proper" 194 | echo "tools for further handling them. Check the 'README' file, it" 195 | echo "often tells you about the needed prerequisites for installing" 196 | echo "this package. You may also peek at any GNU archive site, in" 197 | echo "case some other package contains this missing '$1' program." 198 | ;; 199 | esac 200 | } 201 | 202 | give_advice "$1" | sed -e '1s/^/WARNING: /' \ 203 | -e '2,$s/^/ /' >&2 204 | 205 | # Propagate the correct exit status (expected to be 127 for a program 206 | # not found, 63 for a program that failed due to version mismatch). 207 | exit $st 208 | 209 | # Local variables: 210 | # eval: (add-hook 'before-save-hook 'time-stamp) 211 | # time-stamp-start: "scriptversion=" 212 | # time-stamp-format: "%:y-%02m-%02d.%02H" 213 | # time-stamp-time-zone: "UTC0" 214 | # time-stamp-end: "; # UTC" 215 | # End: 216 | -------------------------------------------------------------------------------- /mkpkgindb.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "/* automatically generated, DO NOT EDIT */" 4 | echo '#define CREATE_DRYDB " \' 5 | ${SEDCMD} -e 's/$/ \\/' -e 's/\"/\\\"/g' pkgin.sql 6 | echo '"' 7 | -------------------------------------------------------------------------------- /order.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2015 The NetBSD Foundation, Inc. 3 | * All rights reserved. 4 | * 5 | * This code is derived from software contributed to The NetBSD Foundation 6 | * by Emile "iMil" Heitor . 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 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 | * SUCH DAMAGE. 28 | */ 29 | 30 | #include "pkgin.h" 31 | 32 | /* 33 | * Order package lists to ensure they are correctly ordered when passed to 34 | * pkg_add or pkg_delete. 35 | * 36 | * Incorrect ordering of pkg_add arguments results in packages being installed 37 | * twice, as pkg_add will pull in dependencies automatically. 38 | * 39 | * Incorrect ordering of pkg_delete arguments will work as we explicitly use 40 | * "pkg_delete -f" but we don't want to rely on that. 41 | */ 42 | 43 | /* 44 | * Order removals for pkg_delete. 45 | * 46 | * Note that this function removes entries from the supplied impact list as an 47 | * optimisation, as currently all callers of it do not re-use it. 48 | */ 49 | Plisthead * 50 | order_remove(Plisthead *impacthead) 51 | { 52 | int i, maxlevel = 0; 53 | Pkglist *p, *tmpp; 54 | Plisthead *removehead; 55 | 56 | SLIST_FOREACH(p, impacthead, next) 57 | if (p->level > maxlevel) 58 | maxlevel = p->level; 59 | 60 | removehead = init_head(); 61 | 62 | /* 63 | * Move entries from impacthead to removehead according to dependency 64 | * level. 65 | */ 66 | for (i = 0; i <= maxlevel; i++) { 67 | SLIST_FOREACH_SAFE(p, impacthead, next, tmpp) { 68 | if (p->level != i) 69 | continue; 70 | 71 | /* 72 | * We do not support shooting yourself in the foot. 73 | */ 74 | if (strcmp(p->lpkg->name, "pkg_install") == 0) { 75 | fprintf(stderr, MSG_NOT_REMOVING_PKG_INSTALL); 76 | continue; 77 | } 78 | 79 | SLIST_REMOVE(impacthead, p, Pkglist, next); 80 | SLIST_INSERT_HEAD(removehead, p, next); 81 | } 82 | } 83 | 84 | return removehead; 85 | } 86 | 87 | /* 88 | * Download order, sorted alphabetically. 89 | * 90 | * All we do is skip any packages not marked for download by pkgin_install() 91 | * and then insert based on sorted PKGNAME. 92 | */ 93 | Plisthead * 94 | order_download(Plisthead *impacthead) 95 | { 96 | Plisthead *dlhead; 97 | Pkglist *d, *dsave, *p, *pkg; 98 | 99 | dlhead = init_head(); 100 | 101 | SLIST_FOREACH(p, impacthead, next) { 102 | if (!p->download) 103 | continue; 104 | 105 | pkg = malloc_pkglist(); 106 | pkg->ipkg = p; 107 | 108 | if (SLIST_EMPTY(dlhead)) { 109 | SLIST_INSERT_HEAD(dlhead, pkg, next); 110 | continue; 111 | } 112 | 113 | /* 114 | * Find first existing entry that sorts after us. No doubt 115 | * there is a better algorithm that could be used here... 116 | */ 117 | dsave = NULL; 118 | SLIST_FOREACH(d, dlhead, next) { 119 | if (strcmp(pkg->ipkg->rpkg->full, 120 | d->ipkg->rpkg->full) < 0) 121 | break; 122 | dsave = d; 123 | } 124 | if (dsave) 125 | SLIST_INSERT_AFTER(dsave, pkg, next); 126 | else 127 | SLIST_INSERT_HEAD(dlhead, pkg, next); 128 | } 129 | 130 | return dlhead; 131 | } 132 | 133 | /* 134 | * Order the list of packages to install based on their dependency level, so 135 | * that dependencies are installed first. 136 | */ 137 | Plisthead * 138 | order_install(Plisthead *impacthead) 139 | { 140 | Plisthead *installhead; 141 | Pkglist *p, *pkg, *savepi = NULL; 142 | int i, minlevel = 0, maxlevel = 0; 143 | 144 | /* Record highest dependency level on impact list */ 145 | SLIST_FOREACH(p, impacthead, next) { 146 | if (p->level > maxlevel) 147 | maxlevel = p->level; 148 | if (p->level < minlevel) 149 | minlevel = p->level; 150 | } 151 | 152 | installhead = init_head(); 153 | 154 | /* 155 | * Perform the first loop only considering packages that are being 156 | * installed. 157 | */ 158 | for (i = minlevel; i <= maxlevel; i++) { 159 | SLIST_FOREACH(p, impacthead, next) { 160 | if (p->level != i) 161 | continue; 162 | 163 | if (!action_is_install(p->action)) 164 | continue; 165 | 166 | pkg = malloc_pkglist(); 167 | pkg->ipkg = p; 168 | 169 | /* 170 | * Check for pkg_install, and if found, save for later 171 | * insertion at the head of this level. 172 | */ 173 | if (strcmp(p->rpkg->name, "pkg_install") == 0) { 174 | savepi = pkg; 175 | continue; 176 | } 177 | 178 | SLIST_INSERT_HEAD(installhead, pkg, next); 179 | } 180 | 181 | /* 182 | * Put pkg_install at the head of this level so that the newer 183 | * version is used for as many installs as possible. It isn't 184 | * guaranteed that this is the lowest level as there are cases 185 | * where pkg_install can depend on other packages. 186 | */ 187 | if (savepi != NULL) { 188 | SLIST_INSERT_HEAD(installhead, savepi, next); 189 | savepi = NULL; 190 | } 191 | } 192 | 193 | /* 194 | * Now handle removals. These must be performed first in case there 195 | * are file conflicts. 196 | */ 197 | for (i = 0; i <= maxlevel; i++) { 198 | SLIST_FOREACH(p, impacthead, next) { 199 | if (p->level != i) 200 | continue; 201 | if (!action_is_remove(p->action)) 202 | continue; 203 | pkg = malloc_pkglist(); 204 | pkg->ipkg = p; 205 | SLIST_INSERT_HEAD(installhead, pkg, next); 206 | } 207 | } 208 | 209 | return installhead; 210 | } 211 | -------------------------------------------------------------------------------- /pkg_check.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2015 The NetBSD Foundation, Inc. 3 | * All rights reserved. 4 | * 5 | * This code is derived from software contributed to The NetBSD Foundation 6 | * by Emile "iMil" Heitor . 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 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 | * SUCH DAMAGE. 28 | */ 29 | 30 | #include 31 | #include "pkgin.h" 32 | 33 | /* 34 | * Check that REQUIRES is satisifed for incoming packages. As the check 35 | * happens before install, we have to exclude any REQUIRES for libraries under 36 | * PREFIX as they may not exist yet. 37 | * 38 | * TODO: Record what will be installed from PROVIDES and enable check for files 39 | * under PREFIX. 40 | */ 41 | int 42 | pkg_met_reqs(Plisthead *impacthead) 43 | { 44 | struct stat sb; 45 | Plistnumbered *reqhead; 46 | Pkglist *pkg, *req; 47 | size_t len; 48 | int met_reqs = 1; 49 | 50 | len = strlen(PREFIX) - 1; 51 | 52 | SLIST_FOREACH(pkg, impacthead, next) { 53 | if (!action_is_install(pkg->action)) 54 | continue; 55 | 56 | reqhead = rec_pkglist(REMOTE_REQUIRES, pkg->rpkg->full); 57 | if (reqhead == NULL) 58 | continue; 59 | 60 | SLIST_FOREACH(req, reqhead->P_Plisthead, next) { 61 | if (strncmp(req->full, PREFIX, len) == 0) 62 | continue; 63 | if (stat(req->full, &sb) < 0) { 64 | printf(MSG_REQT_NOT_PRESENT, req->full, 65 | pkg->rpkg->full); 66 | pkg->action = ACTION_UNMET_REQ; 67 | met_reqs = 0; 68 | } 69 | } 70 | 71 | free_pkglist(&reqhead->P_Plisthead); 72 | free(reqhead); 73 | } 74 | 75 | return met_reqs; 76 | } 77 | 78 | /* 79 | * Check if an incoming remote package matches an entry in the local CONFLICTS 80 | * table, and if so return the match that can be used by callers to identify 81 | * which local package is responsible. 82 | */ 83 | char * 84 | pkg_conflicts(Pkglist *pkg) 85 | { 86 | Pkglist *p; 87 | int i, slot; 88 | 89 | if (is_empty_plistarray(l_conflicthead)) 90 | return NULL; 91 | 92 | slot = pkg_hash_entry(pkg->rpkg->name, CONFLICTS_HASH_SIZE); 93 | SLIST_FOREACH(p, &l_conflicthead->head[slot], next) { 94 | for (i = 0; i < p->patcount; i++) { 95 | if (pkg_match(p->patterns[i], pkg->rpkg->full)) 96 | return p->patterns[i]; 97 | } 98 | } 99 | 100 | /* 101 | * We also need to check slot 0 if not already checked as that's where 102 | * any CONFLICTS that have a complicated pattern and no pkgbase are 103 | * stored. 104 | */ 105 | if (slot == 0) 106 | return NULL; 107 | SLIST_FOREACH(p, &l_conflicthead->head[0], next) { 108 | for (i = 0; i < p->patcount; i++) { 109 | if (pkg_match(p->patterns[i], pkg->rpkg->full)) 110 | return p->patterns[i]; 111 | } 112 | } 113 | 114 | return NULL; 115 | } 116 | 117 | void 118 | show_prov_req(const char *query, const char *pkgname) 119 | { 120 | const char *out[] = { "provided", "required" }; 121 | const char *say; 122 | char *fullpkgname; 123 | Plistnumbered *plisthead; 124 | Pkglist *plist; 125 | 126 | if ((fullpkgname = unique_pkg(pkgname, REMOTE_PKG)) == NULL) 127 | errx(EXIT_FAILURE, MSG_PKG_NOT_AVAIL, pkgname); 128 | 129 | say = (query == REMOTE_PROVIDES) ? out[0] : out[1]; 130 | 131 | if ((plisthead = rec_pkglist(query, fullpkgname)) == NULL) { 132 | printf(MSG_NO_PROV_REQ, say, fullpkgname); 133 | exit(EXIT_SUCCESS); 134 | } 135 | 136 | printf(MSG_FILES_PROV_REQ, say, fullpkgname); 137 | SLIST_FOREACH(plist, plisthead->P_Plisthead, next) 138 | printf("\t%s\n", plist->full); 139 | 140 | free_pkglist(&plisthead->P_Plisthead); 141 | free(plisthead); 142 | XFREE(fullpkgname); 143 | } 144 | -------------------------------------------------------------------------------- /pkg_infos.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2015 The NetBSD Foundation, Inc. 3 | * All rights reserved. 4 | * 5 | * This code is derived from software contributed to The NetBSD Foundation 6 | * by Emile "iMil" Heitor . 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 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 | * SUCH DAMAGE. 28 | */ 29 | 30 | #include "pkgin.h" 31 | 32 | int 33 | show_pkg_info(char flag, char *pkgname) 34 | { 35 | FILE *fp; 36 | int rv = 0; 37 | char buf[MAXLEN], cmd[BUFSIZ], *fullpkgname, **prepos; 38 | 39 | if ((fullpkgname = unique_pkg(pkgname, REMOTE_PKG)) == NULL) 40 | errx(EXIT_FAILURE, MSG_PKG_NOT_AVAIL, pkgname); 41 | 42 | /* loop through PKG_REPOS */ 43 | for (prepos = pkg_repos; *prepos != NULL; prepos++) { 44 | snprintf(cmd, BUFSIZ, "%s -%c %s/%s%s", 45 | pkg_info, flag, *prepos, fullpkgname, PKG_EXT); 46 | 47 | if ((fp = popen(cmd, "r")) == NULL) 48 | return 1; 49 | 50 | /* 51 | * Historically pkgin skipped blank lines, so we preserve 52 | * that behaviour for now. 53 | */ 54 | while (fgets(buf, MAXLEN, fp) != NULL) { 55 | if (buf[0] != '\n') 56 | printf("%s", buf); 57 | } 58 | 59 | if (pclose(fp) != 0) 60 | rv = 1; 61 | } 62 | 63 | free(fullpkgname); 64 | 65 | return rv; 66 | } 67 | -------------------------------------------------------------------------------- /pkg_install.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 The NetBSD Foundation, Inc. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 | * SUCH DAMAGE. 25 | */ 26 | 27 | /* 28 | * Routines for configuring and using pkg_install utilities. 29 | */ 30 | 31 | #include "pkgin.h" 32 | 33 | char *pkg_add; 34 | char *pkg_admin; 35 | char *pkg_delete; 36 | char *pkg_info; 37 | 38 | /* 39 | * Configure the location to pkg_install used in this instance, either via the 40 | * PKG_INSTALL_DIR environment variable or the default compiled-in location. 41 | */ 42 | void 43 | setup_pkg_install(void) 44 | { 45 | FILE *fp; 46 | char *line, *p; 47 | size_t len; 48 | ssize_t llen; 49 | 50 | p = getenv("PKG_INSTALL_DIR"); 51 | pkg_add = xasprintf("%s/pkg_add", p ? p : PKG_INSTALL_DIR); 52 | pkg_admin = xasprintf("%s/pkg_admin", p ? p : PKG_INSTALL_DIR); 53 | pkg_info = xasprintf("%s/pkg_info", p ? p : PKG_INSTALL_DIR); 54 | pkg_delete = xasprintf("%s/pkg_delete", p ? p : PKG_INSTALL_DIR); 55 | 56 | /* Sanity check */ 57 | if (access(pkg_admin, X_OK) != 0) 58 | err(EXIT_FAILURE, "Cannot execute %s", pkg_admin); 59 | 60 | /* Ensure pkg_install only looks at our specified paths */ 61 | unsetenv("PKG_PATH"); 62 | 63 | /* Get PKG_DBDIR from pkg_admin */ 64 | p = xasprintf("%s config-var PKG_DBDIR", pkg_admin); 65 | 66 | if ((fp = popen(p, "r")) == NULL) 67 | err(EXIT_FAILURE, "Cannot execute '%s'", p); 68 | 69 | line = NULL; len = 0; 70 | while ((llen = getline(&line, &len, fp)) > 0) { 71 | if (line[llen - 1] == '\n') 72 | line[llen - 1] = '\0'; 73 | pkgdb_set_dir(line, 1); 74 | } 75 | pclose(fp); 76 | 77 | free(line); 78 | free(p); 79 | 80 | if (pkgdb_get_dir() == NULL) 81 | errx(EXIT_FAILURE, "Could not determine PKG_DBDIR"); 82 | } 83 | -------------------------------------------------------------------------------- /pkg_str.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2015 The NetBSD Foundation, Inc. 3 | * All rights reserved. 4 | * 5 | * This code is derived from software contributed to The NetBSD Foundation 6 | * by Emile "iMil" Heitor . 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 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 | * SUCH DAMAGE. 28 | */ 29 | 30 | #include "pkgin.h" 31 | 32 | #define GLOBCHARS "{<>[]?*" 33 | 34 | /* 35 | * Return best candidate for a remote package, taking into consideration any 36 | * preferred.conf matches. 37 | */ 38 | int 39 | find_preferred_pkg(const char *pkgname, Pkglist **pkg, char **match) 40 | { 41 | Pkglist *p, *best = NULL; 42 | int i; 43 | char *result = NULL; 44 | 45 | /* Find best match */ 46 | for (i = 0; i < REMOTE_PKG_HASH_SIZE; i++) { 47 | SLIST_FOREACH(p, &r_plisthead[i], next) { 48 | if (!pkg_match(pkgname, p->full)) 49 | continue; 50 | 51 | /* 52 | * Free any previous results first. If we made it past the 53 | * pkg_match then we should get the same result back. 54 | */ 55 | if (result != NULL) { 56 | free(result); 57 | result = NULL; 58 | } 59 | 60 | /* 61 | * Check that the candidate matches any potential 62 | * preferred.conf restrictions, if not then skip. 63 | */ 64 | if (chk_preferred(p->full, &result) != 0) 65 | continue; 66 | 67 | /* Save best match */ 68 | if (best == NULL || version_check(best->full, p->full) == 2) 69 | best = p; 70 | } 71 | } 72 | 73 | /* 74 | * Save match if requested. If there was a successful match then 75 | * return the full package name, otherwise the unsuccessful match 76 | */ 77 | if (match != NULL) 78 | *match = best ? xstrdup(best->full) : result; 79 | 80 | /* 81 | * Save pkglist entry if requested. 82 | */ 83 | if (pkg != NULL) 84 | *pkg = best; 85 | 86 | return (best == NULL) ? 1 : 0; 87 | } 88 | 89 | /** 90 | * \fn unique_pkg 91 | * 92 | * Returns greatest version package matching in full package name form 93 | */ 94 | char * 95 | unique_pkg(const char *pkgname, const char *dest) 96 | { 97 | char *u_pkg = NULL; 98 | Plistnumbered *plist; 99 | Pkglist *best_match = NULL, *current; 100 | 101 | if (exact_pkgfmt(pkgname)) 102 | plist = rec_pkglist(UNIQUE_EXACT_PKG, dest, pkgname); 103 | else 104 | plist = rec_pkglist(UNIQUE_PKG, dest, pkgname); 105 | 106 | if (plist == NULL) 107 | return NULL; 108 | 109 | SLIST_FOREACH(current, plist->P_Plisthead, next) { 110 | /* first result */ 111 | if (best_match == NULL) 112 | best_match = current; 113 | else 114 | if (dewey_cmp(current->version, DEWEY_GT, 115 | best_match->version)) 116 | best_match = current; 117 | } 118 | 119 | if (best_match != NULL) 120 | u_pkg = xstrdup(best_match->full); 121 | free_pkglist(&plist->P_Plisthead); 122 | free(plist); 123 | 124 | return u_pkg; 125 | } 126 | 127 | /* 128 | * Return best remote package for a pattern and optional pkgpath, or NULL if no 129 | * valid match. 130 | */ 131 | Pkglist * 132 | find_remote_pkg(const char *pattern, const char *pkgname, const char *pkgpath) 133 | { 134 | Pkglist *p, *pkg = NULL; 135 | size_t size = REMOTE_PKG_HASH_SIZE; 136 | size_t slot = 0; 137 | 138 | /* 139 | * If a valid pkgname is supplied then the caller has indicated that 140 | * the pattern will always match the specific pkgname, and so we can 141 | * optimise the lookup by only considering the hash entry for that 142 | * pkgname. For example pattern is "foo>=1<2" and pkgname is "foo". 143 | */ 144 | if (pkgname) { 145 | slot = pkg_hash_entry(pkgname, REMOTE_PKG_HASH_SIZE); 146 | size = slot + 1; 147 | } 148 | 149 | for (; slot < size; slot++) { 150 | SLIST_FOREACH(p, &r_plisthead[slot], next) { 151 | if (!pkg_match(pattern, p->full)) 152 | continue; 153 | 154 | /* 155 | * If pkgpath is specified then the remote entry must 156 | * match, to avoid newer releases being pulled in when 157 | * the user may have specified a particular version in 158 | * the past. 159 | */ 160 | if (pkgpath && pkgstrcmp(pkgpath, p->pkgpath) != 0) 161 | continue; 162 | 163 | if (chk_preferred(p->full, NULL) != 0) 164 | continue; 165 | 166 | /* 167 | * Save match if we haven't seen one yet, or if this 168 | * one is a higher version number than the current best 169 | * match. 170 | */ 171 | if (pkg == NULL || 172 | version_check(pkg->full, p->full) == 2) 173 | pkg = p; 174 | } 175 | } 176 | 177 | return pkg; 178 | } 179 | 180 | /* 181 | * Find first match of a locally-installed package for a package pattern. 182 | * Returns a Pkglist entry on success or NULL on failure. 183 | * 184 | * Just return the first match. While technically we could find the "best" 185 | * result for an alternate match it doesn't make any practical sense. 186 | */ 187 | Pkglist * 188 | find_local_pkg(const char *pattern, const char *pkgname) 189 | { 190 | Pkglist *p; 191 | size_t size = LOCAL_PKG_HASH_SIZE; 192 | size_t slot = 0; 193 | 194 | /* 195 | * If a valid pkgname is supplied then the caller has indicated that 196 | * the pattern will always match the specific pkgname, and so we can 197 | * optimise the lookup by only considering the hash entry for that 198 | * pkgname. For example pattern is "foo>=1<2" and pkgname is "foo". 199 | */ 200 | if (pkgname) { 201 | slot = pkg_hash_entry(pkgname, LOCAL_PKG_HASH_SIZE); 202 | size = slot + 1; 203 | } 204 | 205 | for (; slot < size; slot++) { 206 | SLIST_FOREACH(p, &l_plisthead[slot], next) { 207 | if (pkg_match(pattern, p->full)) { 208 | return p; 209 | } 210 | } 211 | } 212 | 213 | return NULL; 214 | } 215 | 216 | /* basic full package format detection */ 217 | int 218 | exact_pkgfmt(const char *pkgname) 219 | { 220 | char *p; 221 | 222 | if ((p = strrchr(pkgname, '-')) == NULL) 223 | return 0; 224 | 225 | p++; 226 | 227 | /* naive assumption, will fail with foo-100bar, hopefully, there's 228 | * only a few packages needing to be fully specified 229 | */ 230 | return isdigit((int)*p); 231 | } 232 | 233 | /* similar to opattern.c's pkg_order but without pattern */ 234 | int 235 | version_check(char *first_pkg, char *second_pkg) 236 | { 237 | char *first_ver, *second_ver; 238 | 239 | first_ver = strrchr(first_pkg, '-'); 240 | second_ver = strrchr(second_pkg, '-'); 241 | 242 | if (first_ver == NULL) 243 | return 2; 244 | if (second_ver == NULL) 245 | return 1; 246 | 247 | if (dewey_cmp(first_ver + 1, DEWEY_GT, second_ver + 1)) 248 | return 1; 249 | else 250 | return 2; 251 | } 252 | 253 | /* 254 | * Compare string values between two packages. Often in pkgin the comparison 255 | * in question allows both to be NULL, for example with pkg_summary fields 256 | * that are optional, so this function returns true if both are NULL. 257 | * 258 | * This also acts as a safe wrapper for strcmp(). 259 | */ 260 | int 261 | pkgstrcmp(const char *p1, const char *p2) 262 | { 263 | if (p1 == NULL && p2 == NULL) 264 | return 0; 265 | 266 | if (p1 == NULL) 267 | return -1; 268 | else if (p2 == NULL) 269 | return 1; 270 | 271 | return (strcmp(p1, p2)); 272 | } 273 | 274 | /* 275 | * To speed up lookups of patterns we use hashes keyed on the package name if 276 | * available. This function extracts a single package name from a pattern if 277 | * that is the only possible package that can satisfy the pattern. 278 | * 279 | * For example, "foo-[0-9]*" and "foo>1" etc can be guaranteed to only match 280 | * for the package name "foo", whereas "{foo,bar}-[0-9]*", "fo{o,b}*>1" can 281 | * not. The latter return NULL and callers will instead have to traverse the 282 | * entire hash. 283 | * 284 | * This is kept relatively conservative as we cannot be sure what creative 285 | * patterns users may come up with in the future. 286 | */ 287 | 288 | char * 289 | pkgname_from_pattern(const char *pattern) 290 | { 291 | char *p, *pkgname; 292 | 293 | /* 294 | * Any alternate matches can be immediately discounted. It may 295 | * be possible in the future to expand these and record all 296 | * possible package names to look up in turn. 297 | */ 298 | if (strpbrk(pattern, "{")) 299 | return NULL; 300 | 301 | pkgname = xstrdup(pattern); 302 | 303 | /* 304 | * Since we discounted alternate matches, any specific version 305 | * matches ("foo>1", "foo<5", etc) are guaranteed to have the 306 | * package name on the left of the first match. 307 | * 308 | * The only thing we need to double check is that the package 309 | * name does not contain any globs (not currently used in 310 | * pkgsrc and highly suspicious, but we do not want to take any 311 | * chances). 312 | */ 313 | if ((p = strpbrk(pkgname, "<>"))) { 314 | *p = '\0'; 315 | if (strpbrk(pkgname, "[]*")) 316 | return NULL; 317 | return pkgname; 318 | } 319 | 320 | /* 321 | * The only other case we support for now is the incredibly common 322 | * "foo-[0-9]*". Any other version match e.g. "foo-1.*" is a little 323 | * too complicated to handle, just in case there is a "*" glob 324 | * somewhere in the package name, or if the package name itself 325 | * contains '-[0-9]*'. 326 | */ 327 | if ((p = strrchr(pkgname, '[')) && --p > pkgname) { 328 | if (strcmp(p, "-[0-9]*") != 0) 329 | return NULL; 330 | *p = '\0'; 331 | if (strpbrk(pkgname, "[]*")) 332 | return NULL; 333 | return pkgname; 334 | } 335 | 336 | return NULL; 337 | } 338 | 339 | /* 340 | * qsort callback to sort alphabetically. 341 | */ 342 | int 343 | sort_pkg_alpha(const void *a, const void *b) 344 | { 345 | return strcmp(*(const char * const *)a, *(const char * const *)b); 346 | } 347 | -------------------------------------------------------------------------------- /pkgin.1.in: -------------------------------------------------------------------------------- 1 | .Dd July 1, 2020 2 | .Dt PKGIN 1 3 | .Os 4 | .Sh NAME 5 | .Nm pkgin 6 | .Nd pkgsrc binary package manager 7 | .Sh SYNOPSIS 8 | .Nm 9 | .Op Fl 46dfhnPpVvy 10 | .Op Fl c Ar chroot_path 11 | .Op Fl l Ar limit_chars 12 | .Op Fl t Ar log_file 13 | .Cm command 14 | .Op Ar package Ar 15 | .Sh DESCRIPTION 16 | .Nm 17 | is a package manager for binary package sets that have been produced by 18 | .Xr pkgsrc 7 . 19 | .Pp 20 | By parsing 21 | .Xr pkg_summary 5 22 | files stored within each configured repository, it supports 23 | installing, upgrading, removing, and querying available packages. 24 | .Sh OPTIONS 25 | The following command line arguments are supported: 26 | .Bl -tag -width 15n -offset 6n 27 | .It Fl 4 28 | Forces 29 | .B pkgin 30 | to only use IPv4 addresses. 31 | .It Fl 6 32 | Forces 33 | .B pkgin 34 | to only use IPv6 addresses. 35 | .It Fl c Ar chroot_path 36 | Enable chrooting 37 | .Nm 38 | in the given repository 39 | .It Fl d 40 | Download only 41 | .It Fl f 42 | Force database update 43 | .It Fl h 44 | Displays help for the command 45 | .It Fl l Ar limit_chars 46 | Only include the packages with the specified 47 | .Dv STATUS FLAGS 48 | .It Fl n 49 | Assumes 50 | .Dq no 51 | as default answer and print results of actions to be taken line per line 52 | .It Fl P 53 | Displays packages versions instead of globs (sd, sfd, srd) 54 | .It Fl p 55 | Displays results in a parsable format 56 | .It Fl t Ar log_file 57 | Logs package browsing (dependencies and impact) to a given log file 58 | .It Fl V 59 | Be verbose when (un)installing 60 | .It Fl v 61 | Displays 62 | .Nm 63 | version 64 | .It Fl y 65 | Assumes 66 | .Dq yes 67 | as default answer, except for autoremove 68 | .El 69 | .Pp 70 | The 71 | .Nm 72 | utility provides several commands: 73 | .Bl -tag -width 12n 74 | .It Cm autoremove 75 | Automatically removes orphan dependencies. 76 | When used with the 77 | .Fl n 78 | flag, it can be used to show packages that are possibly not necessary. 79 | .It Cm avail 80 | Lists all packages available in the repository. 81 | .It Cm clean 82 | Delete downloaded packages from the cache directory. 83 | .It Cm export 84 | Export the list of non-autoremovable packages to stdout (one 85 | category/package by line). 86 | .It Cm import Ar file 87 | Import a list of packages to be installed from file (one 88 | category/package by line) 89 | .It Cm install Ar package Ns | Ns Ar glob Ar 90 | Performs installation or upgrade of package. 91 | If more than one packages are specified on the command-line, all will 92 | be installed (or upgraded). 93 | Instead of a package name, a glob can be specified in order to install 94 | specific versions. 95 | .Pp 96 | Example: 97 | .Dl pkgin install 'mysql-server>=5.6<5.7' 98 | .It Cm keep Ar package Ar 99 | Marks package as "non auto-removable". 100 | A 101 | .Cm keep Ns No -able 102 | package is equivalent to a non-automatic package in 103 | .Xr pkgsrc 7 104 | terminology. 105 | .It Cm list 106 | Lists all packages installed locally on a system. 107 | If the 108 | .Fl l 109 | modifier is added to this command, show only packages matching the 110 | status flag. 111 | .It Cm pkg-build-defs Ar package 112 | Show remote package build definitions. 113 | .It Cm pkg-content Ar package 114 | Show remote package content. 115 | .It Cm pkg-descr Ar package 116 | Show remote package long-description. 117 | .It Cm provides Ar package 118 | Shows what a package provides to others. 119 | .It Cm remove Ar package Ar 120 | Removes package as well as all packages depending on it. 121 | When more than one package are specified, they will all be 122 | uninstalled. 123 | By default, it will prompt you to confirm before package removals. 124 | .It Cm requires Ar package 125 | Shows what a package requires from other packages. 126 | .It Cm search Ar pattern 127 | Performs a regular expression search for the pattern 128 | .Ar pattern 129 | in the repository. 130 | .It Cm show-deps Ar package 131 | Displays all direct dependencies. 132 | .It Cm show-full-deps Ar package 133 | Displays all direct dependencies recursively. 134 | .It Cm show-rev-deps Ar package 135 | Displays all reverse direct dependencies for package. 136 | If more than one package is specified, 137 | .Nm 138 | will show recursively reverse direct dependencies for all packages on 139 | the command-line. 140 | .It Cm show-category Ar category 141 | Show packages belonging to 142 | .Ar category . 143 | .It Cm show-pkg-category Ar package 144 | Show package category. 145 | .It Cm show-keep 146 | Display 147 | .Dq non auto-removable 148 | packages. 149 | .It Cm show-no-keep 150 | Display 151 | .Dq auto-removable 152 | packages. 153 | .It Cm unkeep Ar package Ar 154 | Marks package as 155 | .Dq auto-removable . 156 | If no other package depends on it, it will be removed when using the 157 | .Cm autoremove 158 | modifier. 159 | It is equivalent to an 160 | .Dv automatic 161 | package in 162 | .Xr pkgsrc 7 163 | terminology. 164 | .It Cm update 165 | Creates and populates the initial database of locally installed 166 | packages and available packages (from the remote 167 | .Xr pkg_summary 5 168 | list). 169 | This is done automatically when 170 | .Nm 171 | is first used, when the system package database has been modified, or 172 | when 173 | .Nm 174 | is upgraded to a new database version. 175 | .It Cm upgrade 176 | Upgrade all packages to the newest versions available in the 177 | repository. 178 | .El 179 | .Sh STATUS FLAGS 180 | When using the 181 | .Fl l 182 | flag along with the list command, the following status flag must be set: 183 | .Bl -tag -width 2n 184 | .It \&= 185 | The installed version of the package is current. 186 | .It \&< 187 | The installed version of the package is older than the current 188 | version. 189 | .It \&> 190 | The installed version of the package is newer than the current version. 191 | .El 192 | .Sh ENVIRONMENT 193 | .Bl -tag -width 10n 194 | .It Ev PKG_REPOS 195 | The 196 | .Ev PKG_REPOS 197 | environment variable can be pointed to a suitable repository or a list 198 | of space separated repositories in order to override 199 | .Pa /usr/pkg/etc/pkgin/repositories.conf . 200 | .El 201 | .Sh FILES 202 | .Bl -tag -width 12n 203 | .It Pa /usr/pkg/etc/pkgin/repositories.conf 204 | This file contains a list of repository URIs that 205 | .Nm 206 | will use. 207 | It may contain macros 208 | .Dv $arch 209 | to define the machine hardware platform and 210 | .Dv $osrelease 211 | to define the release version for the operating system (as reported by 212 | .Xr uname 1 ) . 213 | .It Pa /usr/pkg/etc/pkgin/preferred.conf 214 | This file contains a list of preferences regarding packages to be 215 | installed or upgraded. 216 | Each line defines a package preference taking the form of a simple 217 | .Xr glob 3 , 218 | such as: 219 | .Pp 220 | .Dl autoconf=2.69.* 221 | .Dl mysql-server<5.6 222 | .Dl php>=5.4 223 | .It Pa /var/db/pkgin 224 | This directory contains the individual files and 225 | directories used by 226 | .Nm 227 | listed below. 228 | .It Pa /var/db/pkgin/cache 229 | This directory contains the packages downloaded by 230 | .Nm . 231 | It is safe to empty it if necessary by running: 232 | .Pp 233 | .Dl # pkgin clean 234 | .It Pa /var/db/pkgin/pkgin.db 235 | This is the main 236 | .Nm pkgin 237 | sqlite database. 238 | This format has been chosen in order to parse, query, match and order 239 | packages using the SQL language thus making packages list manipulation 240 | a lot easier. 241 | .It Pa /var/db/pkgin/pkg_install-err.log 242 | This file contains errors and warnings given by 243 | .Xr pkg_add 1 244 | and 245 | .Xr pkg_delete 1 , 246 | which are the tools called by 247 | .Nm 248 | to manipulate packages themselves. 249 | .It Pa /var/db/pkgin/sql.log 250 | This file contains SQL errors that might have occurred on a sqlite 251 | query. 252 | Mainly for debugging purposes. 253 | .El 254 | .Sh EXAMPLES 255 | Setup the initial database: 256 | .Pp 257 | .Dl # vi /usr/pkg/etc/pkgin/repositories.conf 258 | .Dl https://cdn.netbsd.org/pub/pkgsrc/packages/NetBSD/$arch/9.0/All 259 | .Pp 260 | .Dl # pkgin update 261 | .Pp 262 | Listing all packages available in the repository: 263 | .Pp 264 | .Dl # pkgin avail 265 | .Pp 266 | Search for specific packages: 267 | .Pp 268 | .Dl # pkgin search '^abook|lbdb|mutt|xlhtml' 269 | .Dl abook-0.6.1 Text-based addressbook program 270 | .Dl lbdb-0.48.1nb1 The little brother's database 271 | .Dl mutt-1.14.5 = Text-based MIME mail client with PGP & S/MIME support 272 | .Dl xlhtml-0.5nb2 Microsoft xls/ppt to HTML converter 273 | .Pp 274 | .Dl # pkgin search '^php-' 275 | .Dl php-7.4.7 PHP Hypertext Preprocessor version 7.4 276 | .Dl php-7.3.19 PHP Hypertext Preprocessor version 7.3 277 | .Dl php-7.2.31nb1 PHP Hypertext Preprocessor version 7.2 278 | .Dl php-5.6.40nb3 PHP Hypertext Preprocessor version 5.6 279 | .Dl php-mode-1.13.1 PHP editing mode for Emacs 280 | .Pp 281 | Install packages and their dependencies: 282 | .Pp 283 | .Dl # pkgin install abook lbdb mutt xlhtml 284 | .Pp 285 | .Dl # pkgin install 'php>=7.3<7.4' 286 | .Pp 287 | Upgrade all packages: 288 | .Pp 289 | .Dl # pkgin upgrade 290 | .Pp 291 | Remove packages and their reverse dependencies: 292 | .Pp 293 | .Dl # pkgin remove mutt 294 | .Pp 295 | Remove orphaned dependencies: 296 | .Pp 297 | .Dl # pkgin autoremove 298 | .Sh SEE ALSO 299 | .Xr pkg_add 1 , 300 | .Xr pkg_info 1 , 301 | .Xr pkg_summary 5 , 302 | .Xr pkgsrc 7 303 | .Sh AUTHORS 304 | .Bl -tag -width 25n 305 | .It Emile Ao iMil Ac Heitor 306 | Initial work and ongoing development. 307 | .It Jonathan Perkin 308 | Primary maintainer 0.9.0 onwards. 309 | .El 310 | .Sh CONTRIBUTORS 311 | .Bl -tag -width 25n 312 | .It Jeremy C. Reed 313 | Testing and refinements. 314 | .It Arnaud Ysmal 315 | Tests and patches 316 | .It Claude Charpentier 317 | SQLite schema, and SQL queries debugging. 318 | .It Guillaume Lasmayous 319 | Man page 320 | .It Antonio Huete Jimenez 321 | .Dx 322 | port 323 | .It Min Sik Kim 324 | Darwin port 325 | .It Filip Hajny 326 | SunOS port 327 | .It Baptiste Daroussin 328 | .Fx 329 | port and patches 330 | .It Gautam B.T. 331 | MINIX port 332 | .It Thomas Ao wiz Ac Klausner 333 | Testing and refinements. 334 | .It Youri Ao yrmt Ac Mouton 335 | OSX testing and patches 336 | .El 337 | .Sh BUGS 338 | We're hunting them. 339 | -------------------------------------------------------------------------------- /pkgin.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE [PKGDB] ( 2 | "PKGDB_MTIME" INTEGER, 3 | "PKGDB_NTIME" INTEGER 4 | ); 5 | 6 | CREATE TABLE [REPOS] ( 7 | "REPO_URL" TEXT UNIQUE, 8 | "REPO_MTIME" INTEGER 9 | ); 10 | 11 | CREATE TABLE [REMOTE_PKG] ( 12 | "PKG_ID" INTEGER PRIMARY KEY, 13 | "FULLPKGNAME" TEXT UNIQUE, 14 | "PKGNAME" TEXT, 15 | "PKGVERS" TEXT, 16 | "BUILD_DATE" TEXT, 17 | "COMMENT" TEXT, 18 | "LICENSE" TEXT NULL, 19 | "PKGTOOLS_VERSION" TEXT, 20 | "HOMEPAGE" TEXT NULL, 21 | "OS_VERSION" TEXT, 22 | "PKGPATH" TEXT, 23 | "PKG_OPTIONS" TEXT NULL, 24 | "CATEGORIES" TEXT, 25 | "SIZE_PKG" TEXT, 26 | "FILE_SIZE" TEXT, 27 | "OPSYS" TEXT, 28 | "REPOSITORY" TEXT 29 | ); 30 | 31 | CREATE TABLE [LOCAL_PKG] ( 32 | "PKG_ID" INTEGER PRIMARY KEY, 33 | "FULLPKGNAME" TEXT UNIQUE, 34 | "PKGNAME" TEXT, 35 | "PKGVERS" TEXT, 36 | "BUILD_DATE" TEXT, 37 | "COMMENT" TEXT, 38 | "LICENSE" TEXT NULL, 39 | "PKGTOOLS_VERSION" TEXT, 40 | "HOMEPAGE" TEXT NULL, 41 | "OS_VERSION" TEXT, 42 | "PKGPATH" TEXT, 43 | "PKG_OPTIONS" TEXT NULL, 44 | "CATEGORIES" TEXT, 45 | "SIZE_PKG" TEXT, 46 | "FILE_SIZE" TEXT, 47 | "OPSYS" TEXT, 48 | "PKG_KEEP" INTEGER NULL 49 | ); 50 | 51 | /* 52 | * CONFLICTS 53 | */ 54 | CREATE TABLE local_conflicts ( 55 | pkg_id INTEGER, 56 | pattern TEXT NOT NULL, 57 | pkgbase TEXT 58 | ); 59 | CREATE INDEX idx_local_conflicts_pkg_id ON local_conflicts ( 60 | pkg_id ASC 61 | ); 62 | CREATE INDEX idx_local_conflicts_pattern ON local_conflicts ( 63 | pattern ASC 64 | ); 65 | CREATE TABLE remote_conflicts ( 66 | pkg_id INTEGER, 67 | pattern TEXT NOT NULL, 68 | pkgbase TEXT 69 | ); 70 | CREATE INDEX idx_remote_conflicts_pkg_id ON remote_conflicts ( 71 | pkg_id ASC 72 | ); 73 | CREATE INDEX idx_remote_conflicts_pattern ON remote_conflicts ( 74 | pattern ASC 75 | ); 76 | 77 | /* 78 | * DEPENDS 79 | */ 80 | CREATE TABLE local_depends ( 81 | pkg_id INTEGER, 82 | pattern TEXT NOT NULL, 83 | pkgbase TEXT 84 | ); 85 | CREATE INDEX idx_local_depends_pkg_id ON local_depends ( 86 | pkg_id ASC 87 | ); 88 | CREATE INDEX idx_local_depends_pattern ON local_depends ( 89 | pattern ASC 90 | ); 91 | CREATE TABLE remote_depends ( 92 | pkg_id INTEGER, 93 | pattern TEXT NOT NULL, 94 | pkgbase TEXT 95 | ); 96 | CREATE INDEX idx_remote_depends_pkg_id ON remote_depends ( 97 | pkg_id ASC 98 | ); 99 | CREATE INDEX idx_remote_depends_pattern ON remote_depends ( 100 | pattern ASC 101 | ); 102 | 103 | /* 104 | * PROVIDES 105 | */ 106 | CREATE TABLE local_provides ( 107 | pkg_id INTEGER, 108 | filename TEXT 109 | ); 110 | CREATE INDEX idx_local_provides_pkg_id ON local_provides ( 111 | pkg_id ASC 112 | ); 113 | CREATE INDEX idx_local_provides_filename ON local_provides ( 114 | filename ASC 115 | ); 116 | CREATE TABLE remote_provides ( 117 | pkg_id INTEGER, 118 | filename TEXT 119 | ); 120 | CREATE INDEX idx_remote_provides_pkg_id ON remote_provides ( 121 | pkg_id ASC 122 | ); 123 | CREATE INDEX idx_remote_provides_filename ON remote_provides ( 124 | filename ASC 125 | ); 126 | 127 | /* 128 | * REQUIRES 129 | */ 130 | CREATE TABLE local_requires ( 131 | pkg_id INTEGER, 132 | filename TEXT 133 | ); 134 | CREATE INDEX idx_local_requires_pkg_id ON local_requires ( 135 | pkg_id ASC 136 | ); 137 | CREATE INDEX idx_local_requires_filename ON local_requires ( 138 | filename ASC 139 | ); 140 | CREATE TABLE remote_requires ( 141 | pkg_id INTEGER, 142 | filename TEXT 143 | ); 144 | CREATE INDEX idx_remote_requires_pkg_id ON remote_requires ( 145 | pkg_id ASC 146 | ); 147 | CREATE INDEX idx_remote_requires_filename ON remote_requires ( 148 | filename ASC 149 | ); 150 | 151 | /* 152 | * SUPERSEDES 153 | */ 154 | CREATE TABLE remote_supersedes ( 155 | pkg_id INTEGER, 156 | pattern TEXT NOT NULL, 157 | pkgbase TEXT 158 | ); 159 | CREATE INDEX idx_remote_supersedes_pkg_id ON remote_supersedes ( 160 | pkg_id ASC 161 | ); 162 | CREATE INDEX idx_remote_supersedes_pattern ON remote_supersedes ( 163 | pattern ASC 164 | ); 165 | 166 | /* 167 | * +REQUIRED_BY 168 | */ 169 | CREATE TABLE local_required_by ( 170 | pkgname TEXT, 171 | required_by TEXT 172 | ); 173 | CREATE INDEX idx_local_required_by_pkgname ON local_required_by ( 174 | pkgname ASC 175 | ); 176 | CREATE INDEX idx_local_required_by_required_by ON local_required_by ( 177 | required_by ASC 178 | ); 179 | 180 | CREATE INDEX [idx_remote_pkg_category] ON [REMOTE_PKG] ( 181 | [CATEGORIES] ASC 182 | ); 183 | CREATE INDEX [idx_remote_pkg_comment] ON [REMOTE_PKG] ( 184 | [COMMENT] ASC 185 | ); 186 | CREATE INDEX [idx_remote_pkg_name] ON [REMOTE_PKG] ( 187 | [PKGNAME] ASC 188 | ); 189 | CREATE INDEX [idx_local_pkg_category] ON [LOCAL_PKG] ( 190 | [CATEGORIES] ASC 191 | ); 192 | CREATE INDEX [idx_local_pkg_comment] ON [LOCAL_PKG] ( 193 | [COMMENT] ASC 194 | ); 195 | CREATE INDEX [idx_local_pkg_name] ON [LOCAL_PKG] ( 196 | [PKGNAME] ASC 197 | ); 198 | -------------------------------------------------------------------------------- /pkgindb.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2015 The NetBSD Foundation, Inc. 3 | * All rights reserved. 4 | * 5 | * This code is derived from software contributed to The NetBSD Foundation 6 | * by Emile "iMil" Heitor . 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 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 | * SUCH DAMAGE. 28 | */ 29 | 30 | #ifndef _DRYDB_H 31 | #define _DRYDB_H 32 | 33 | #include 34 | #include "pkgindb_create.h" 35 | 36 | extern const char CHECK_DB_LATEST[]; 37 | extern const char DELETE_LOCAL[]; 38 | extern const char DELETE_REMOTE[]; 39 | extern const char DELETE_REMOTE_PKG_REPO[]; 40 | extern const char LOCAL_DIRECT_DEPENDS[]; 41 | extern const char REMOTE_DIRECT_DEPENDS[]; 42 | extern const char LOCAL_REVERSE_DEPENDS[]; 43 | extern const char LOCAL_CONFLICTS[]; 44 | extern const char LOCAL_PROVIDES[]; 45 | extern const char REMOTE_CONFLICTS[]; 46 | extern const char REMOTE_PROVIDES[]; 47 | extern const char REMOTE_REQUIRES[]; 48 | extern const char REMOTE_SUPERSEDES[]; 49 | extern const char KEEP_PKG[]; 50 | extern const char UNKEEP_PKG[]; 51 | extern const char LOCAL_PKGS_QUERY_ASC[]; 52 | extern const char REMOTE_PKGS_QUERY_ASC[]; 53 | extern const char LOCAL_PKGS_QUERY_DESC[]; 54 | extern const char REMOTE_PKGS_QUERY_DESC[]; 55 | extern const char NOKEEP_LOCAL_PKGS[]; 56 | extern const char KEEP_LOCAL_PKGS[]; 57 | extern const char PKG_URL[]; 58 | extern const char DELETE_EMPTY_ROWS[]; 59 | extern const char SELECT_REPO_URLS[]; 60 | extern const char EXISTS_REPO[]; 61 | extern const char INSERT_REPO[]; 62 | extern const char UPDATE_REPO_MTIME[]; 63 | extern const char DELETE_REPO_URL[]; 64 | extern const char INSERT_CONFLICTS[]; 65 | extern const char INSERT_DEPENDS[]; 66 | extern const char INSERT_PROVIDES[]; 67 | extern const char INSERT_REQUIRES[]; 68 | extern const char INSERT_SUPERSEDES[]; 69 | extern const char INSERT_REQUIRED_BY[]; 70 | extern const char UNIQUE_PKG[]; 71 | extern const char UNIQUE_EXACT_PKG[]; 72 | extern const char EXPORT_KEEP_LIST[]; 73 | extern const char GET_PKGNAME_BY_PKGPATH[]; 74 | extern const char SHOW_ALL_CATEGORIES[]; 75 | 76 | #define LOCAL_PKG "LOCAL_PKG" 77 | #define REMOTE_PKG "REMOTE_PKG" 78 | 79 | #define PDB_OK 0 80 | #define PDB_ERR -1 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /pkgindb_queries.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2015 The NetBSD Foundation, Inc. 3 | * All rights reserved. 4 | * 5 | * This code is derived from software contributed to The NetBSD Foundation 6 | * by Emile "iMil" Heitor . 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 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 | * SUCH DAMAGE. 28 | */ 29 | 30 | /* 31 | * This query checks the compatibility of the current database, and should be 32 | * one that either completes or fails due to an SQL error based on the most 33 | * recent schema change. Returned rows are ignored, so choose a query that 34 | * runs quickly. 35 | */ 36 | const char CHECK_DB_LATEST[] = 37 | "SELECT pkgbase " 38 | " FROM local_conflicts " 39 | " LIMIT 1;"; 40 | 41 | const char DELETE_LOCAL[] = 42 | "DELETE FROM LOCAL_PKG;" 43 | "DELETE FROM LOCAL_CONFLICTS;" 44 | "DELETE FROM LOCAL_DEPENDS;" 45 | "DELETE FROM LOCAL_PROVIDES;" 46 | "DELETE FROM LOCAL_REQUIRES;" 47 | "DELETE FROM LOCAL_REQUIRED_BY;"; 48 | 49 | const char DELETE_REMOTE[] = 50 | "DELETE FROM %s " 51 | " WHERE pkg_id IN " 52 | " (SELECT pkg_id " 53 | " FROM remote_pkg " 54 | " WHERE repository GLOB %Q || '*' " 55 | " );"; 56 | 57 | const char DELETE_REMOTE_PKG_REPO[] = 58 | "DELETE FROM REMOTE_PKG WHERE REPOSITORY = %Q;"; 59 | 60 | const char LOCAL_DIRECT_DEPENDS[] = 61 | "SELECT pattern, pkgbase " 62 | " FROM local_depends, local_pkg " 63 | " WHERE fullpkgname = %Q " 64 | " AND local_depends.pkg_id = local_pkg.pkg_id;"; 65 | 66 | const char REMOTE_DIRECT_DEPENDS[] = 67 | "SELECT pattern, pkgbase " 68 | " FROM remote_depends, remote_pkg " 69 | " WHERE fullpkgname = %Q " 70 | " AND remote_depends.pkg_id = remote_pkg.pkg_id;"; 71 | 72 | const char LOCAL_REVERSE_DEPENDS[] = 73 | "SELECT required_by, local_pkg.pkgname, local_pkg.pkg_keep " 74 | " FROM local_pkg " 75 | " LEFT JOIN local_required_by " 76 | " ON local_pkg.fullpkgname = local_required_by.required_by " 77 | " WHERE local_required_by.pkgname = %Q;"; 78 | 79 | const char LOCAL_CONFLICTS[] = 80 | "SELECT DISTINCT pattern, pkgbase " 81 | " FROM local_conflicts;"; 82 | 83 | const char LOCAL_PROVIDES[] = 84 | "SELECT filename " 85 | " FROM local_provides;"; 86 | 87 | const char REMOTE_CONFLICTS[] = 88 | "SELECT local_pkg.fullpkgname " 89 | " FROM local_conflicts, local_pkg " 90 | " WHERE local_conflicts.pattern = %Q " 91 | " AND local_conflicts.pkg_id = local_pkg.pkg_id;"; 92 | 93 | const char REMOTE_PROVIDES[] = 94 | "SELECT filename " 95 | " FROM remote_provides, remote_pkg " 96 | " WHERE fullpkgname = %Q " 97 | " AND remote_provides.pkg_id = remote_pkg.pkg_id;"; 98 | 99 | const char REMOTE_REQUIRES[] = 100 | "SELECT filename " 101 | " FROM remote_requires, remote_pkg " 102 | " WHERE fullpkgname = %Q " 103 | " AND remote_requires.pkg_id = remote_pkg.pkg_id;"; 104 | 105 | const char REMOTE_SUPERSEDES[] = 106 | "SELECT pattern, pkgbase, pkgname " 107 | " FROM remote_supersedes " 108 | " LEFT JOIN remote_pkg " 109 | " ON remote_supersedes.pkg_id = remote_pkg.pkg_id;"; 110 | 111 | const char KEEP_PKG[] = 112 | "UPDATE LOCAL_PKG SET PKG_KEEP = 1 WHERE PKGNAME = %Q;"; 113 | const char UNKEEP_PKG[] = 114 | "UPDATE LOCAL_PKG SET PKG_KEEP = NULL WHERE PKGNAME = %Q;"; 115 | 116 | /* for upgrades, prefer higher versions to be at the top of SLIST */ 117 | const char LOCAL_PKGS_QUERY_ASC[] = 118 | "SELECT FULLPKGNAME,PKGNAME,PKGVERS,BUILD_DATE," 119 | "COMMENT,FILE_SIZE,SIZE_PKG,CATEGORIES,PKGPATH,PKG_KEEP " 120 | "FROM LOCAL_PKG " 121 | "ORDER BY FULLPKGNAME ASC;"; 122 | 123 | /* present packages by repository appearance to avoid conflicts between repos */ 124 | const char REMOTE_PKGS_QUERY_ASC[] = 125 | "SELECT FULLPKGNAME,PKGNAME,PKGVERS,BUILD_DATE," 126 | "COMMENT,FILE_SIZE,SIZE_PKG,CATEGORIES,PKGPATH " 127 | "FROM REMOTE_PKG " 128 | "INNER JOIN REPOS WHERE REMOTE_PKG.REPOSITORY = REPOS.REPO_URL " 129 | "ORDER BY REPOS.ROWID, FULLPKGNAME ASC;"; 130 | 131 | /* for displays, prefer lower versions to be at the top of SLIST*/ 132 | const char LOCAL_PKGS_QUERY_DESC[] = 133 | "SELECT FULLPKGNAME,PKGNAME,PKGVERS,BUILD_DATE," 134 | "COMMENT,FILE_SIZE,SIZE_PKG,CATEGORIES,PKGPATH " 135 | "FROM LOCAL_PKG " 136 | "ORDER BY FULLPKGNAME DESC;"; 137 | 138 | const char REMOTE_PKGS_QUERY_DESC[] = 139 | "SELECT FULLPKGNAME,PKGNAME,PKGVERS,BUILD_DATE," 140 | "COMMENT,FILE_SIZE,SIZE_PKG,CATEGORIES,PKGPATH " 141 | "FROM REMOTE_PKG " 142 | "ORDER BY FULLPKGNAME DESC;"; 143 | 144 | const char NOKEEP_LOCAL_PKGS[] = 145 | "SELECT fullpkgname,pkgname,pkgpath,comment " 146 | " FROM local_pkg " 147 | " WHERE pkg_keep IS NULL " 148 | " ORDER BY fullpkgname DESC;"; 149 | 150 | const char KEEP_LOCAL_PKGS[] = 151 | "SELECT fullpkgname,pkgname,pkgpath,comment " 152 | " FROM local_pkg " 153 | " WHERE pkg_keep IS NOT NULL" 154 | " ORDER BY fullpkgname DESC;"; 155 | 156 | const char PKG_URL[] = 157 | "SELECT REPOSITORY FROM REMOTE_PKG WHERE FULLPKGNAME = %Q;"; 158 | 159 | const char DELETE_EMPTY_ROWS[] = 160 | "DELETE FROM REMOTE_PKG WHERE PKGNAME IS NULL;"; 161 | 162 | const char SELECT_REPO_URLS[] = 163 | "SELECT REPO_URL FROM REPOS;"; 164 | 165 | const char EXISTS_REPO[] = 166 | "SELECT COUNT(*) FROM REPOS WHERE REPO_URL = %Q;"; 167 | 168 | const char INSERT_REPO[] = 169 | "INSERT INTO REPOS (REPO_URL, REPO_MTIME) VALUES (%Q, 0);"; 170 | 171 | const char UPDATE_REPO_MTIME[] = 172 | "UPDATE REPOS SET REPO_MTIME = %lld WHERE REPO_URL = %Q;"; 173 | 174 | const char DELETE_REPO_URL[] = 175 | "DELETE FROM REPOS WHERE REPO_URL = %Q;"; 176 | 177 | const char INSERT_CONFLICTS[] = 178 | "INSERT INTO %s (pkg_id, pattern, pkgbase) VALUES (%d, %Q, %Q);"; 179 | 180 | const char INSERT_DEPENDS[] = 181 | "INSERT INTO %s (pkg_id, pattern, pkgbase) VALUES (%d, %Q, %Q);"; 182 | 183 | const char INSERT_PROVIDES[] = 184 | "INSERT INTO %s (PKG_ID, FILENAME) VALUES (%d, %Q);"; 185 | 186 | const char INSERT_REQUIRES[] = 187 | "INSERT INTO %s (PKG_ID, FILENAME) VALUES (%d, %Q);"; 188 | 189 | const char INSERT_SUPERSEDES[] = 190 | "INSERT INTO %s (pkg_id, pattern, pkgbase) VALUES (%d, %Q, %Q);"; 191 | 192 | const char INSERT_REQUIRED_BY[] = 193 | "INSERT INTO LOCAL_REQUIRED_BY (PKGNAME, REQUIRED_BY) VALUES (%Q, %Q);"; 194 | 195 | const char UNIQUE_PKG[] = 196 | "SELECT FULLPKGNAME, PKGVERS FROM %s WHERE PKGNAME = %Q;"; 197 | 198 | const char UNIQUE_EXACT_PKG[] = 199 | "SELECT FULLPKGNAME, PKGVERS FROM %s WHERE FULLPKGNAME GLOB %Q || '*';"; 200 | 201 | const char EXPORT_KEEP_LIST[] = 202 | "SELECT PKGPATH FROM LOCAL_PKG " 203 | "WHERE PKG_KEEP IS NOT NULL AND PKGPATH IS NOT NULL " 204 | "ORDER BY PKG_ID DESC;"; 205 | 206 | const char GET_PKGNAME_BY_PKGPATH[] = 207 | "SELECT FULLPKGNAME FROM REMOTE_PKG WHERE PKGPATH = %Q;"; 208 | 209 | const char SHOW_ALL_CATEGORIES[] = 210 | "SELECT DISTINCT CATEGORIES FROM REMOTE_PKG WHERE " 211 | "CATEGORIES NOT LIKE '%% %%' ORDER BY CATEGORIES DESC;"; 212 | -------------------------------------------------------------------------------- /preferred.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2015 The NetBSD Foundation, Inc. 3 | * All rights reserved. 4 | * 5 | * This code is derived from software contributed to The NetBSD Foundation 6 | * by Emile "iMil" Heitor . 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 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 | * SUCH DAMAGE. 28 | * 29 | */ 30 | 31 | #include "pkgin.h" 32 | 33 | static Preflisthead prefhead; 34 | 35 | void 36 | load_preferred(void) 37 | { 38 | FILE *fp; 39 | Preflist *pref; 40 | size_t len = 0; 41 | ssize_t llen; 42 | char *line = NULL, *p; 43 | const char *cmp = "=<>"; 44 | 45 | if ((fp = fopen(PKGIN_CONF"/"PREF_FILE, "r")) == NULL) 46 | return; 47 | 48 | SLIST_INIT(&prefhead); 49 | 50 | while ((llen = getline(&line, &len, fp)) > 0) { 51 | if (line[0] == '\n' || line[0] == '#') 52 | continue; 53 | 54 | if ((p = strpbrk(line, cmp)) == NULL) 55 | continue; 56 | 57 | trimcr(line); 58 | 59 | /* 60 | * The preferred.conf syntax for equality uses "=" to separate 61 | * the package name and version (e.g. "foo=1.*"). This needs 62 | * to be converted to the "foo-1.*" form for pkg_match(). 63 | */ 64 | if (*p == '=') 65 | *p = '-'; 66 | 67 | pref = xmalloc(sizeof(Preflist)); 68 | pref->glob = xstrdup(line); 69 | *p = '\0'; 70 | pref->pkg = xstrdup(line); 71 | SLIST_INSERT_HEAD(&prefhead, pref, next); 72 | } 73 | 74 | fclose(fp); 75 | } 76 | 77 | void 78 | free_preferred(void) 79 | { 80 | Preflist *pref; 81 | 82 | while (!SLIST_EMPTY(&prefhead)) { 83 | pref = SLIST_FIRST(&prefhead); 84 | SLIST_REMOVE_HEAD(&prefhead, next); 85 | free(pref->pkg); 86 | free(pref->glob); 87 | free(pref); 88 | } 89 | } 90 | 91 | static char * 92 | is_preferred(char *fullpkg) 93 | { 94 | Preflist *pref; 95 | char pkg[BUFSIZ]; 96 | 97 | XSTRCPY(pkg, fullpkg); 98 | trunc_str(pkg, '-', STR_BACKWARD); 99 | 100 | SLIST_FOREACH(pref, &prefhead, next) { 101 | if (strcmp(pref->pkg, pkg) == 0) 102 | return pref->glob; 103 | } 104 | 105 | return NULL; 106 | } 107 | 108 | /* 109 | * Given a full package name in "pkg" (e.g. "foo-1.0"), look for any 110 | * corresponding entries for "foo" in preferred.conf and if so check that 111 | * any version requirements are satisfied. 112 | * 113 | * Return 0 if either there are no matches or the requirement is satisfied, 114 | * otherwise return 1. If there is a match it is stored in *matchp. 115 | */ 116 | uint8_t 117 | chk_preferred(char *pkg, char **matchp) 118 | { 119 | char *pref; 120 | 121 | if ((pref = is_preferred(pkg)) == NULL) { 122 | /* No matches for pkg in preferred.conf */ 123 | if (matchp != NULL) 124 | *matchp = NULL; 125 | return 0; 126 | } 127 | 128 | if (matchp != NULL) 129 | *matchp = xstrdup(pref); 130 | 131 | return (pkg_match(pref, pkg) == 0) ? 1 : 0; 132 | } 133 | -------------------------------------------------------------------------------- /preferred.conf: -------------------------------------------------------------------------------- 1 | # This file might contain simple rules that specify packages versions to be 2 | # installed. Allowed operators are '<', '>' and '='. 3 | # 4 | # For example, in order to force PHP to stay at version below 5.6: 5 | # 6 | # php<5.6 7 | # 8 | # MySQL server must be greater or equal than version 5.5: 9 | # 10 | # mysql-server>=5.5 11 | # 12 | # For a specific reason, cmake should stay at version 3.0.2: 13 | # 14 | # cmake=3.0.2 15 | -------------------------------------------------------------------------------- /repositories.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Pkgin repositories list 3 | # 4 | # Simply add repositories URIs one below the other 5 | # 6 | # WARNING: order matters, duplicates will not be added, if two 7 | # repositories hold the same package, it will be fetched from 8 | # the first one listed in this file. 9 | # 10 | # This file format supports the following macros: 11 | # $arch to define the machine hardware platform 12 | # $osrelease to define the release version for the operating system 13 | # 14 | # Remote ftp repository 15 | # 16 | # ftp://ftp.netbsd.org/pub/pkgsrc/packages/NetBSD/$arch/5.1/All 17 | # 18 | # Remote http repository 19 | # 20 | # http://mirror-master.dragonflybsd.org/packages/$arch/DragonFly-$osrelease/stable/All 21 | # 22 | # Local repository (must contain a pkg_summary.gz or bz2) 23 | # 24 | # file:///usr/pkgsrc/packages/All 25 | -------------------------------------------------------------------------------- /selection.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2015 The NetBSD Foundation, Inc. 3 | * All rights reserved. 4 | * 5 | * This code is derived from software contributed to The NetBSD Foundation 6 | * by Emile "iMil" Heitor . 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 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 | * SUCH DAMAGE. 28 | */ 29 | 30 | #include 31 | #include "pkgin.h" 32 | 33 | void 34 | export_keep(void) 35 | { 36 | Plistnumbered *plisthead; 37 | Pkglist *plist; 38 | 39 | if ((plisthead = rec_pkglist(EXPORT_KEEP_LIST)) == NULL) 40 | errx(EXIT_FAILURE, MSG_EMPTY_LOCAL_PKGLIST); 41 | /* yes we could output directly from the sql reading, but we would lose 42 | * some genericity. 43 | */ 44 | SLIST_FOREACH(plist, plisthead->P_Plisthead, next) 45 | printf("%s\n", plist->full); 46 | 47 | free_pkglist(&plisthead->P_Plisthead); 48 | free(plisthead); 49 | } 50 | 51 | void 52 | import_keep(int do_inst, const char *import_file) 53 | { 54 | size_t list_size = 0; 55 | char **pkglist = NULL, *match; 56 | char input[BUFSIZ], fullpkgname[BUFSIZ], query[BUFSIZ]; 57 | FILE *fp; 58 | 59 | if ((fp = fopen(import_file, "r")) == NULL) 60 | err(EXIT_FAILURE, MSG_ERR_OPEN, import_file); 61 | 62 | while (fgets(input, BUFSIZ, fp) != NULL) { 63 | if (!isalnum((int)input[0])) 64 | continue; 65 | 66 | trimcr(input); 67 | if (strchr(input, '/') != NULL) { 68 | sqlite3_snprintf(BUFSIZ, query, GET_PKGNAME_BY_PKGPATH, 69 | input); 70 | 71 | if ((pkgindb_doquery(query, 72 | pdb_get_value, fullpkgname)) == PDB_OK) 73 | match = xstrdup(fullpkgname); 74 | else 75 | match = NULL; 76 | } else 77 | match = unique_pkg(input, REMOTE_PKG); 78 | 79 | if (match == NULL) { 80 | fprintf(stderr, MSG_PKG_NOT_AVAIL, input); 81 | continue; 82 | } 83 | /* 1st element + NULL */ 84 | pkglist = xrealloc(pkglist, (list_size + 2) * sizeof(char *)); 85 | pkglist[list_size] = match; 86 | pkglist[++list_size] = NULL; 87 | } 88 | fclose(fp); 89 | 90 | if (pkglist == NULL) 91 | errx(EXIT_FAILURE, MSG_EMPTY_IMPORT_LIST); 92 | 93 | pkgin_install(pkglist, do_inst, 0); 94 | 95 | free_list(pkglist); 96 | } 97 | -------------------------------------------------------------------------------- /sqlite_callbacks.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2015 The NetBSD Foundation, Inc. 3 | * All rights reserved. 4 | * 5 | * This code is derived from software contributed to The NetBSD Foundation 6 | * by Emile "iMil" Heitor . 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 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 | * SUCH DAMAGE. 28 | */ 29 | 30 | #include "pkgin.h" 31 | 32 | /** 33 | * SQLite callback, record package list 34 | */ 35 | int 36 | pdb_rec_list(void *param, int argc, char **argv, char **colname) 37 | { 38 | Pkglist *plist; 39 | Plistnumbered *plisthead = (Plistnumbered *)param; 40 | int i; 41 | 42 | if (argv == NULL) 43 | return PDB_ERR; 44 | 45 | /* FULLPKGNAME was empty, probably a package installed 46 | * from pkgsrc or wip that does not exist in 47 | * pkg_summary(5), return 48 | */ 49 | if (argv[0] == NULL) 50 | return PDB_ERR; 51 | 52 | plist = malloc_pkglist(); 53 | 54 | /* 55 | * rec_pkglist is used for convenience for REQUIRES / PROVIDES 56 | * otherwise contains FULLPKGNAME 57 | */ 58 | plist->full = xstrdup(argv[0]); 59 | 60 | for (i = 1; i < argc; i++) { 61 | if (argv[i] == NULL) 62 | continue; 63 | 64 | if (strcmp(colname[i], "PKGNAME") == 0) { 65 | plist->name = xstrdup(argv[i]); 66 | continue; 67 | } 68 | if (strcmp(colname[i], "PKGVERS") == 0) { 69 | plist->version = xstrdup(argv[i]); 70 | continue; 71 | } 72 | if (strcmp(colname[i], "BUILD_DATE") == 0) { 73 | plist->build_date = xstrdup(argv[i]); 74 | continue; 75 | } 76 | if (strcmp(colname[i], "COMMENT") == 0) { 77 | plist->comment = xstrdup(argv[i]); 78 | continue; 79 | } 80 | if (strcmp(colname[i], "PKGPATH") == 0) { 81 | plist->pkgpath = xstrdup(argv[i]); 82 | continue; 83 | } 84 | if (strcmp(colname[i], "CATEGORIES") == 0) { 85 | plist->category = xstrdup(argv[i]); 86 | continue; 87 | } 88 | if (strcmp(colname[i], "FILE_SIZE") == 0) { 89 | plist->file_size = strtol(argv[i], (char **)NULL, 10); 90 | continue; 91 | } 92 | if (strcmp(colname[i], "SIZE_PKG") == 0) { 93 | plist->size_pkg = strtol(argv[i], (char **)NULL, 10); 94 | continue; 95 | } 96 | } 97 | 98 | SLIST_INSERT_HEAD(plisthead->P_Plisthead, plist, next); 99 | plisthead->P_count++; 100 | 101 | return PDB_OK; 102 | } 103 | 104 | /* 105 | * SQLite callback for LOCAL_CONFLICTS etc, record a pattern and optional 106 | * PKGBASE to a Plistarray. 107 | * 108 | * argv0: pattern 109 | * argv1: pkgbase, may be NULL if it cannot be determined from pattern 110 | */ 111 | int 112 | record_pattern_to_array(void *param, int argc, char **argv, char **colname) 113 | { 114 | Plistarray *depends = (Plistarray *)param; 115 | Pkglist *d; 116 | int slot; 117 | 118 | if (argv == NULL) 119 | return PDB_ERR; 120 | 121 | d = malloc_pkglist(); 122 | d->patterns = xmalloc(2 * sizeof(char *)); 123 | d->patterns[0] = xstrdup(argv[0]); 124 | d->patterns[1] = NULL; 125 | d->patcount = 1; 126 | 127 | /* 128 | * XXX: default slot if no pkgbase available, should we allocate one 129 | * outside of the normal range for these? 130 | */ 131 | slot = 0; 132 | 133 | if (argv[1]) { 134 | d->name = xstrdup(argv[1]); 135 | slot = pkg_hash_entry(d->name, depends->size); 136 | } 137 | 138 | SLIST_INSERT_HEAD(&depends->head[slot], d, next); 139 | 140 | return PDB_OK; 141 | } 142 | -------------------------------------------------------------------------------- /tools.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2015 The NetBSD Foundation, Inc. 3 | * All rights reserved. 4 | * 5 | * This code is derived from software contributed to The NetBSD Foundation 6 | * by Emile "iMil" Heitor . 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 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 | * SUCH DAMAGE. 28 | */ 29 | 30 | #include "tools.h" 31 | 32 | int 33 | charcount(char *str, char c) 34 | { 35 | char *p; 36 | int count = 0; 37 | 38 | if (str == NULL) 39 | return 0; 40 | 41 | for (p = str; *p != '\0'; p++) 42 | if (*p == c) 43 | count++; 44 | 45 | return count; 46 | } 47 | 48 | /* 49 | * Remove trailing \n or \r\n, returning length of resulting string. 50 | */ 51 | size_t 52 | trimcr(char *str) 53 | { 54 | size_t len; 55 | 56 | if (str == NULL) 57 | return (0); 58 | 59 | len = strlen(str); 60 | 61 | if (str[len - 1] == '\n') 62 | str[--len] = '\0'; 63 | 64 | if (str[len - 1] == '\r') 65 | str[--len] = '\0'; 66 | 67 | return (len); 68 | } 69 | 70 | void 71 | free_list(char **list) 72 | { 73 | int i; 74 | 75 | if (list != NULL) { 76 | for (i = 0; list[i] != NULL; i++) 77 | XFREE(list[i]); 78 | XFREE(list); 79 | } 80 | } 81 | 82 | void 83 | trunc_str(char *str, char limit, int direction) 84 | { 85 | char *p; 86 | 87 | switch(direction) { 88 | case STR_FORWARD: 89 | if ((p = strchr(str, limit)) != NULL) 90 | *p = '\0'; 91 | break; 92 | case STR_BACKWARD: 93 | if ((p = strrchr(str, limit)) != NULL) 94 | *p = '\0'; 95 | break; 96 | } 97 | } 98 | 99 | __attribute__((__format__ (__printf__, 2, 3))) 100 | void 101 | do_log(const char *path, const char *fmt, ...) 102 | { 103 | FILE *fp; 104 | char buffer[MAXLEN]; 105 | 106 | va_list args; 107 | va_start(args, fmt); 108 | vsnprintf(buffer, MAXLEN, fmt, args); 109 | 110 | fp = fopen(path, "a"); 111 | fputs(buffer, fp); 112 | fclose(fp); 113 | 114 | va_end(args); 115 | } 116 | 117 | /* Return architecture name or NULL in case of failure */ 118 | char * 119 | getosarch(void) 120 | { 121 | return xstrdup(MACHINE_ARCH); 122 | } 123 | 124 | /* Return release numbers or NULL in case of failure */ 125 | char * 126 | getosrelease(void) 127 | { 128 | struct utsname un; 129 | char *ret, *p; 130 | 131 | memset(&un, 0, sizeof(un)); 132 | if (uname(&un) < 0) 133 | return NULL; 134 | 135 | ret = xstrdup(un.release); 136 | 137 | for (p = ret; isdigit((int)*p) || *p == '.'; p++); 138 | *p = '\0'; 139 | 140 | return ret; 141 | } 142 | 143 | /* 144 | * Find all coincidences found in big string that match oldsub 145 | * substring and replace them with newsub. 146 | * Returns an allocated buffer that needs to be freed later. 147 | */ 148 | char * 149 | strreplace(char *str, const char *from, const char *to) 150 | { 151 | size_t fromlen, tolen, i; 152 | char *p, *ret, buf[MAXLEN]; 153 | 154 | memset(buf, 0, sizeof(buf)); 155 | 156 | fromlen = strlen(from); 157 | tolen = strlen(to); 158 | 159 | for (i = 0, p = str; *p != '\0';) { 160 | if (strncmp(p, from, fromlen) == 0) { 161 | strlcat(buf, to, sizeof(buf)); 162 | p += fromlen; 163 | i += tolen; 164 | } else { 165 | buf[i] = *p; 166 | p++; 167 | i++; 168 | } 169 | } 170 | buf[i] = '\0'; 171 | 172 | ret = xstrdup(buf); 173 | return(ret); 174 | } 175 | 176 | int 177 | check_yesno(uint8_t default_answer) 178 | { 179 | const struct Answer { 180 | const uint8_t numval; 181 | const char charval; 182 | } answer[] = { { ANSW_NO, 'n' }, { ANSW_YES, 'y' } }; 183 | 184 | uint8_t r, reverse_answer; 185 | int c; 186 | 187 | if (yesflag) 188 | return ANSW_YES; 189 | else if (noflag) 190 | return ANSW_NO; 191 | 192 | /* reverse answer is default's answer opposite (you don't say!) */ 193 | reverse_answer = (default_answer == ANSW_YES) ? ANSW_NO : ANSW_YES; 194 | 195 | if (default_answer == answer[ANSW_YES].numval) 196 | printf(MSG_PROCEED_YES); 197 | else 198 | printf(MSG_PROCEED_NO); 199 | fflush(stdout); 200 | 201 | c = tolower(getchar()); 202 | 203 | /* default answer */ 204 | if (c == answer[default_answer].charval || c == '\n') 205 | r = answer[default_answer].numval; 206 | /* reverse answer */ 207 | else if (c == answer[reverse_answer].charval) 208 | r = answer[reverse_answer].numval; 209 | /* bad key was given, default to No */ 210 | else 211 | r = ANSW_NO; 212 | 213 | /* avoid residual char */ 214 | if (c != '\n') 215 | while((c = getchar()) != '\n' && c != EOF) 216 | continue; 217 | 218 | return r; 219 | } 220 | -------------------------------------------------------------------------------- /tools.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2015 The NetBSD Foundation, Inc. 3 | * All rights reserved. 4 | * 5 | * This code is derived from software contributed to The NetBSD Foundation 6 | * by Emile "iMil" Heitor . 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 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 | * SUCH DAMAGE. 28 | */ 29 | 30 | #ifndef _TOOLS_H 31 | #define _TOOLS_H 32 | 33 | #include "config.h" 34 | 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | 44 | #include 45 | #include 46 | 47 | #if defined(HAVE_BSD_LIBUTIL_H) 48 | #include 49 | #elif defined(HAVE_LIBUTIL_H) 50 | #include 51 | #elif defined(HAVE_UTIL_H) 52 | #include 53 | #endif 54 | 55 | #include "external/lib.h" 56 | 57 | #ifndef HN_AUTOSCALE 58 | #include "external/humanize_number.h" 59 | #endif 60 | 61 | #ifdef LINE_MAX 62 | #define MAXLEN LINE_MAX 63 | #else 64 | #define MAXLEN 2048 65 | #endif 66 | #define STR_FORWARD 0 67 | #define STR_BACKWARD 1 68 | 69 | #define DSTSRC_CHK(dst, src) \ 70 | if (dst == NULL) { \ 71 | warn("NULL destination"); \ 72 | break; \ 73 | } \ 74 | if (src == NULL) { \ 75 | warn("NULL source"); \ 76 | break; \ 77 | } 78 | 79 | 80 | #define XSTRCPY(dst, src) \ 81 | do { \ 82 | DSTSRC_CHK(dst, src); \ 83 | strcpy(dst, src); \ 84 | } while (/* CONSTCOND */ 0) 85 | 86 | #define XSTRCAT(dst, src) \ 87 | do { \ 88 | DSTSRC_CHK(dst, src); \ 89 | strcat(dst, src); \ 90 | } while (/* CONSTCOND */ 0) 91 | 92 | #define XFREE(elm) \ 93 | do { \ 94 | if (elm != NULL) { \ 95 | free(elm); \ 96 | elm = NULL; \ 97 | } \ 98 | } while (/* CONSTCOND */ 0) 99 | 100 | #define KVPRINTF(k, v) \ 101 | printf("key: %s, val: %s\n", k, v); \ 102 | 103 | #define ANSW_NO 0 104 | #define ANSW_YES 1 105 | #define MSG_PROCEED_YES "proceed ? [Y/n] " 106 | #define MSG_PROCEED_NO "proceed ? [y/N] " 107 | 108 | /* those need to be initialized (main.c) */ 109 | extern uint8_t yesflag; 110 | extern uint8_t noflag; 111 | 112 | extern int charcount(char *, char); 113 | extern size_t trimcr(char *); 114 | extern void free_list(char **); 115 | extern void do_log(const char *, const char *, ...); 116 | extern void trunc_str(char *, char, int); 117 | extern char *strreplace(char *, const char *, const char *); 118 | extern char *getosarch(void); 119 | extern char *getosrelease(void); 120 | extern int check_yesno(uint8_t); 121 | 122 | #endif 123 | --------------------------------------------------------------------------------