├── src ├── error.c ├── main.c ├── misc.c ├── path.c ├── pkgdb.c ├── sys.c ├── untgz.c ├── message.c ├── sigtrap.c ├── taction.c ├── cmd-list.c ├── cmd-install.c ├── cmd-private.h ├── cmd-upgrade.c ├── Makefile.am ├── cmd-remove.c └── cmd-common.c ├── include ├── sys.h ├── bench.h ├── error.h ├── misc.h ├── path.h ├── pkgdb.h ├── untgz.h ├── commands.h ├── message.h ├── sigtrap.h ├── taction.h ├── Makefile.am └── cmd-common.h ├── tests ├── test-rm.c ├── test-mkdir.c ├── test-path.c ├── test-untgz.c ├── test-parsers.c ├── test-blacklist.c ├── test-pkgtools-speed.sh ├── blacklist └── Makefile.am ├── docs ├── blogs │ ├── blog1.html │ ├── blog2.html │ ├── blog3.html │ └── blog4.html ├── web │ ├── common.php │ ├── img │ │ ├── freshmeat.gif │ │ └── linuxlinks.gif │ ├── dl │ │ └── .htaccess │ ├── .htaccess │ ├── docs.php │ ├── howto.php │ ├── style.css │ ├── dloads.php │ ├── index.php │ └── history.php ├── devel │ ├── footer.html │ ├── index.doc │ ├── header.html │ └── Doxyfile ├── Makefile.am └── spkg.8 ├── slack-required ├── .valgrindrc ├── .gdbinit ├── libspkg.pc.in ├── autogen.sh ├── slack-desc ├── .gitignore ├── Makefile.am ├── spkg.SlackBuild ├── INSTALL ├── README.md ├── COPYING ├── BENCHMARKS ├── TODO ├── configure.ac └── NEWS /src/error.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gapan/spkg/HEAD/src/error.c -------------------------------------------------------------------------------- /src/main.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gapan/spkg/HEAD/src/main.c -------------------------------------------------------------------------------- /src/misc.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gapan/spkg/HEAD/src/misc.c -------------------------------------------------------------------------------- /src/path.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gapan/spkg/HEAD/src/path.c -------------------------------------------------------------------------------- /src/pkgdb.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gapan/spkg/HEAD/src/pkgdb.c -------------------------------------------------------------------------------- /src/sys.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gapan/spkg/HEAD/src/sys.c -------------------------------------------------------------------------------- /src/untgz.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gapan/spkg/HEAD/src/untgz.c -------------------------------------------------------------------------------- /include/sys.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gapan/spkg/HEAD/include/sys.h -------------------------------------------------------------------------------- /src/message.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gapan/spkg/HEAD/src/message.c -------------------------------------------------------------------------------- /src/sigtrap.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gapan/spkg/HEAD/src/sigtrap.c -------------------------------------------------------------------------------- /src/taction.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gapan/spkg/HEAD/src/taction.c -------------------------------------------------------------------------------- /include/bench.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gapan/spkg/HEAD/include/bench.h -------------------------------------------------------------------------------- /include/error.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gapan/spkg/HEAD/include/error.h -------------------------------------------------------------------------------- /include/misc.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gapan/spkg/HEAD/include/misc.h -------------------------------------------------------------------------------- /include/path.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gapan/spkg/HEAD/include/path.h -------------------------------------------------------------------------------- /include/pkgdb.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gapan/spkg/HEAD/include/pkgdb.h -------------------------------------------------------------------------------- /include/untgz.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gapan/spkg/HEAD/include/untgz.h -------------------------------------------------------------------------------- /src/cmd-list.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gapan/spkg/HEAD/src/cmd-list.c -------------------------------------------------------------------------------- /tests/test-rm.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gapan/spkg/HEAD/tests/test-rm.c -------------------------------------------------------------------------------- /include/commands.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gapan/spkg/HEAD/include/commands.h -------------------------------------------------------------------------------- /include/message.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gapan/spkg/HEAD/include/message.h -------------------------------------------------------------------------------- /include/sigtrap.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gapan/spkg/HEAD/include/sigtrap.h -------------------------------------------------------------------------------- /include/taction.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gapan/spkg/HEAD/include/taction.h -------------------------------------------------------------------------------- /src/cmd-install.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gapan/spkg/HEAD/src/cmd-install.c -------------------------------------------------------------------------------- /src/cmd-private.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gapan/spkg/HEAD/src/cmd-private.h -------------------------------------------------------------------------------- /src/cmd-upgrade.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gapan/spkg/HEAD/src/cmd-upgrade.c -------------------------------------------------------------------------------- /tests/test-mkdir.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gapan/spkg/HEAD/tests/test-mkdir.c -------------------------------------------------------------------------------- /tests/test-path.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gapan/spkg/HEAD/tests/test-path.c -------------------------------------------------------------------------------- /tests/test-untgz.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gapan/spkg/HEAD/tests/test-untgz.c -------------------------------------------------------------------------------- /docs/blogs/blog1.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gapan/spkg/HEAD/docs/blogs/blog1.html -------------------------------------------------------------------------------- /docs/blogs/blog2.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gapan/spkg/HEAD/docs/blogs/blog2.html -------------------------------------------------------------------------------- /docs/blogs/blog3.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gapan/spkg/HEAD/docs/blogs/blog3.html -------------------------------------------------------------------------------- /docs/blogs/blog4.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gapan/spkg/HEAD/docs/blogs/blog4.html -------------------------------------------------------------------------------- /docs/web/common.php: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gapan/spkg/HEAD/docs/web/common.php -------------------------------------------------------------------------------- /slack-required: -------------------------------------------------------------------------------- 1 | Judy >= 1.0.3 2 | glib >= 2.2.1 3 | popt >= 1.7 4 | zlib >= 1.1.4 5 | -------------------------------------------------------------------------------- /tests/test-parsers.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gapan/spkg/HEAD/tests/test-parsers.c -------------------------------------------------------------------------------- /tests/test-blacklist.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gapan/spkg/HEAD/tests/test-blacklist.c -------------------------------------------------------------------------------- /docs/web/img/freshmeat.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gapan/spkg/HEAD/docs/web/img/freshmeat.gif -------------------------------------------------------------------------------- /docs/web/img/linuxlinks.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gapan/spkg/HEAD/docs/web/img/linuxlinks.gif -------------------------------------------------------------------------------- /tests/test-pkgtools-speed.sh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gapan/spkg/HEAD/tests/test-pkgtools-speed.sh -------------------------------------------------------------------------------- /.valgrindrc: -------------------------------------------------------------------------------- 1 | --leak-check=full 2 | --leak-resolution=high 3 | --show-reachable=yes 4 | --log-file=.valgrind.log 5 | -------------------------------------------------------------------------------- /tests/blacklist: -------------------------------------------------------------------------------- 1 | bla 2 | bla 3 | ble 4 | boo 5 | # sdfgsdfg 6 | # sdfasdf 7 | 8 | 9 | asdfasdf 10 | asdf asd -------------------------------------------------------------------------------- /docs/devel/footer.html: -------------------------------------------------------------------------------- 1 |
2 | Documentation for $projectname, $datetime. 3 |
4 | 5 | 6 | -------------------------------------------------------------------------------- /.gdbinit: -------------------------------------------------------------------------------- 1 | set logging file .gdb.log 2 | set logging overwrite on 3 | set logging on 4 | set print pretty on 5 | set args -v -r .root -i aaa_elflibs-10.2.0-i486-4.tgz 6 | file ./spkg 7 | r 8 | -------------------------------------------------------------------------------- /docs/web/dl/.htaccess: -------------------------------------------------------------------------------- 1 | Options +Indexes 2 | IndexOptions +FancyIndexing +FoldersFirst +SuppressDescription 3 | IndexIgnore .ht* 4 | AddDefaultCharset ISO-8859-2 5 | 6 | Order allow,deny 7 | Allow from all 8 | -------------------------------------------------------------------------------- /libspkg.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@exec_prefix@ 3 | libdir=@libdir@ 4 | includedir=@includedir@ 5 | 6 | Name: libspkg 7 | Description: spkg library 8 | Version: @VERSION@ 9 | Requires: glib-2.0 10 | Libs: -L${libdir} -lspkg 11 | Cflags: -I${includedir}/libspkg 12 | -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | mkdir -p m4 4 | 5 | srcdir=`dirname $0` 6 | test -z "$srcdir" && srcdir=. 7 | 8 | ORIGDIR=`pwd` 9 | cd $srcdir 10 | 11 | autoreconf -f -v --install || exit 1 12 | cd $ORIGDIR || exit $? 13 | 14 | $srcdir/configure --enable-maintainer-mode "$@" 15 | -------------------------------------------------------------------------------- /docs/web/.htaccess: -------------------------------------------------------------------------------- 1 | Order allow,deny 2 | Allow from all 3 | 4 | 5 | Order allow,deny 6 | Deny from all 7 | 8 | 9 | DirectoryIndex index.php 10 | 11 | #AuthType Basic 12 | #AuthName "megiWeb restricted area" 13 | #AuthUserFile /home/ftpsite/megous.com/www/.htpasswd 14 | -------------------------------------------------------------------------------- /slack-desc: -------------------------------------------------------------------------------- 1 | spkg: spkg (The Unofficial Slackware Package Manager) 2 | spkg: 3 | spkg: spkg is extremly fast package manager based on the idea 4 | spkg: of pkgtools from Slackware. 5 | spkg: 6 | spkg: Author: Ondrej Jirman 7 | spkg: 8 | spkg: 9 | spkg: 10 | spkg: 11 | spkg: 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | .deps 3 | Makefile 4 | Makefile.in 5 | aclocal.m4 6 | autom4te.cache 7 | compile 8 | config.guess 9 | config.h 10 | config.h.in 11 | config.log 12 | config.status 13 | config.sub 14 | configure 15 | depcomp 16 | install-sh 17 | libtool 18 | ltmain.sh 19 | m4 20 | missing 21 | stamp-h1 22 | *.o 23 | *.a 24 | libspkg.pc 25 | src/spkg 26 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | ACLOCAL_AMFLAGS = -I m4 2 | AUTOMAKE_OPTIONS = foreign 3 | SUBDIRS = src include docs tests 4 | 5 | EXTRA_DIST = BENCHMARKS libspkg.pc.in slack-desc slack-required spkg.SlackBuild 6 | CLEANFILES = libspkg.pc 7 | 8 | if !STATIC_SPKG_ONLY 9 | pkgconfigdir = $(libdir)/pkgconfig 10 | pkgconfig_DATA = libspkg.pc 11 | endif 12 | 13 | docdir = $(prefix)/doc/spkg-$(VERSION) 14 | doc_DATA = COPYING INSTALL NEWS TODO README.md BENCHMARKS 15 | -------------------------------------------------------------------------------- /docs/web/docs.php: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Documentation

4 | 5 |

Developer's documentation for spkg is included in the source code 6 | package, but you can also download 7 | it separately.

8 | 9 |

Online Documentation

10 | 11 |

Online developer's documentation is avalibale here.

13 | 14 | 15 | -------------------------------------------------------------------------------- /include/Makefile.am: -------------------------------------------------------------------------------- 1 | EXTRA_DIST = \ 2 | bench.h \ 3 | commands.h \ 4 | error.h \ 5 | message.h \ 6 | misc.h \ 7 | path.h \ 8 | pkgdb.h \ 9 | sigtrap.h \ 10 | sys.h \ 11 | taction.h \ 12 | untgz.h 13 | 14 | if !STATIC_SPKG_ONLY 15 | libspkgincludedir = $(includedir)/libspkg 16 | libspkginclude_HEADERS = \ 17 | commands.h \ 18 | error.h \ 19 | message.h \ 20 | misc.h \ 21 | path.h \ 22 | pkgdb.h \ 23 | sigtrap.h \ 24 | sys.h \ 25 | taction.h \ 26 | untgz.h 27 | endif 28 | -------------------------------------------------------------------------------- /docs/web/howto.php: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Spkg HOWTO

4 | 5 |

This page explains how to get started with spkg.

6 | 7 |

Quick start

8 | 9 |

After successful installation you can start 10 | using spkg to install or upgrade existing packages:

11 | # spkg some-package-1.0-i486-1.tgz 12 | 13 |

To remove existing package do:

14 | # spkg -d some-package 15 | 16 |

For more info see help:

17 | # spkg --help 18 | 19 |

or manpage:

20 | # man spkg 21 | 22 | 23 | -------------------------------------------------------------------------------- /tests/Makefile.am: -------------------------------------------------------------------------------- 1 | AM_CFLAGS= \ 2 | -I$(top_srcdir)/include \ 3 | $(GLIB_CFLAGS) \ 4 | -D_GNU_SOURCE \ 5 | -Wall -Wno-pointer-sign 6 | 7 | noinst_PROGRAMS = \ 8 | test-untgz \ 9 | test-parsers \ 10 | test-path \ 11 | test-mkdir \ 12 | test-blacklist \ 13 | test-rm 14 | 15 | LDADD = $(top_builddir)/src/libspkg.a $(GLIB_LIBS) -lz -lJudy 16 | 17 | test_blacklist_SOURCES = test-blacklist.c 18 | test_untgz_SOURCES = test-untgz.c 19 | test_parsers_SOURCES = test-parsers.c 20 | test_path_SOURCES = test-path.c 21 | test_mkdir_SOURCES = test-mkdir.c 22 | test_rm_SOURCES = test-rm.c 23 | 24 | EXTRA_DIST = test-pkgtools-speed.sh 25 | -------------------------------------------------------------------------------- /spkg.SlackBuild: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | CWD=`pwd` 4 | VERSION=1.1 5 | ARCH=${ARCH:-i486} 6 | BUILD=1 7 | 8 | rm -rf spkg-$VERSION 9 | tar xzvf spkg-$VERSION.tar.gz 10 | cd spkg-$VERSION 11 | ./configure --sysconfdir=/etc --prefix=/usr --mandir=/usr/man --enable-static-spkg=only 12 | make 13 | make install DESTDIR=$CWD/slack-pkg 14 | gzip -9 $CWD/slack-pkg/usr/man/man8/spkg.8 15 | mkdir -p $CWD/slack-pkg/install 16 | cat slack-desc > $CWD/slack-pkg/install/slack-desc 17 | cat slack-required > $CWD/slack-pkg/install/slack-required 18 | cd $CWD/slack-pkg 19 | makepkg -l y -c n $CWD/spkg-$VERSION-$ARCH-$BUILD.tgz 20 | cd $CWD 21 | rm -rf spkg-$VERSION slack-pkg 22 | -------------------------------------------------------------------------------- /docs/Makefile.am: -------------------------------------------------------------------------------- 1 | man_MANS = spkg.8 2 | 3 | EXTRA_DIST = devel/Doxyfile devel/footer.html \ 4 | devel/header.html devel/index.doc blogs/blog1.html \ 5 | blogs/blog2.html blogs/blog3.html blogs/blog4.html \ 6 | web/.htaccess web/common.php web/dloads.php web/docs.php \ 7 | web/history.php web/howto.php web/index.php web/style.css \ 8 | web/img/freshmeat.gif web/img/linuxlinks.gif web/dl/.htaccess \ 9 | spkg.8 10 | 11 | doxy: 12 | SRCDIR=$(top_srcdir) OUTDIR=$(builddir) \ 13 | PROJECT="$(PACKAGE_NAME)" VERSION="$(PACKAGE_VERSION)" \ 14 | doxygen $(srcdir)/devel/Doxyfile 15 | rm -f api-html/doxygen.png 16 | 17 | distclean-hook: 18 | rm -rf api-html 19 | -------------------------------------------------------------------------------- /docs/devel/index.doc: -------------------------------------------------------------------------------- 1 | /** @page index Main Page 2 | 3 | This is internal documentation of spkg. 4 | 5 | Detailed implementation information for install, upgrade and 6 | remove commands can be found on the @ref cmds_impl page. 7 | 8 | Some info on package database can be found on the @ref db_impl 9 | page. 10 | 11 | */ 12 | 13 | /** @page cmds_impl Commands Implementation 14 | 15 | Common requirements for a command implementation are: 16 | @li only one pass of extracting tgz package is allowed, 17 | @li every command must implement rollback of filesystem changes 18 | up to the point when tgz archive is fully extracted, 19 | @li filesystem inconsistency must be as short as possible, 20 | @li allow for pre/post inst/upgr/remove scripts (pre script 21 | failure may break command execution). 22 | 23 | @section ins Install 24 | 25 | @section upg Upgrade 26 | 27 | @section rem Remove 28 | 29 | */ 30 | 31 | /** @page db_impl Package Database Implementation 32 | 33 | */ 34 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | spkg - The Unofficial Slackware Linux Package Manager 2 | ----------------------------------------------------- 3 | 4 | Dependencies 5 | ------------ 6 | 7 | Judy >= 1.0.3 http://judy.sourceforge.net 8 | glib >= 2.2.1 general purpose C library 9 | popt >= 1.7 command line parser 10 | zlib >= 1.1.4 zlib (de)compression library 11 | 12 | Optional: 13 | lzma >= 4.32.0beta3 lzma utils: http://tukaani.org/lzma 14 | 15 | Lzma utils are not required on compile time. If you want to install 16 | tlz packages just make sure you have lzma binary in your PATH. 17 | 18 | 19 | Installation instructions 20 | ------------------------- 21 | 22 | # ./configure 23 | # make 24 | # make install 25 | 26 | If you are creating package that you want to be usable on older systems 27 | I recomend to use --enable-static-spkg=only confiure option. Resulting 28 | binary will be a bit bloated (800kB), but you will be able to use it 29 | everywhere. 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # spkg 2 | 3 | ## About 4 | 5 | The unofficial Slackware Linux package manager. It is a replacement for the 6 | standard Slackware pkgtools (installpkg/upgradepkg/removepkg). It is 7 | implemented in C and optimized for speed. 8 | 9 | ## Features 10 | 11 | * Simple user interface. Just like pkgtools. 12 | * Fast install, upgrade and remove operations. 13 | * Command to list information about installed packages. 14 | * Dry-run mode, in which filesystem is not touched. 15 | * Safe mode for installing untrusted packages. 16 | * Rollback and safe cancel functionality. 17 | * You can use spkg and pkgtools side by side. 18 | * You can be informed about all actions spkg does if you turn on verbose mode. 19 | * Everything is libified. (see docs) You can implement new commands easily. 20 | 21 | ## License 22 | 23 | The license is Public Domain Software. See COPYING file. 24 | 25 | ## Download 26 | 27 | * https://github.com/gapan/spkg/releases 28 | 29 | ## Issues/Feedback 30 | 31 | * https://github.com/gapan/spkg/issues 32 | 33 | ## Credits 34 | 35 | * Current Maintainer: George Vlahavas (gapan) 36 | * Original Author: Ondrej Jirman (megous) 37 | 38 | -------------------------------------------------------------------------------- /docs/devel/header.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | $title 4 | 5 | 6 | 53 | 54 |
55 | $projectnamedeveloper's documentation 56 |
57 | -------------------------------------------------------------------------------- /src/Makefile.am: -------------------------------------------------------------------------------- 1 | AM_CFLAGS = \ 2 | -I$(top_srcdir)/include \ 3 | $(GLIB_CFLAGS) \ 4 | -DSPKG_CONFDIR=\"$(sysconfdir)/spkg\" \ 5 | -D_GNU_SOURCE \ 6 | -Wall -Wno-pointer-sign 7 | 8 | if ENABLE_ASSUME_BROKEN_PKGDB 9 | AM_CFLAGS += -DASSUME_BROKEN_PKGDB=1 10 | endif 11 | 12 | if LEGACY_CHECKS 13 | AM_CFLAGS += -DLEGACY_CHECKS=1 14 | endif 15 | 16 | EXTRA_DIST = \ 17 | cmd-private.h 18 | 19 | SPKG_LIB_SRC = \ 20 | misc.c \ 21 | error.c \ 22 | sys.c \ 23 | path.c \ 24 | untgz.c \ 25 | pkgdb.c \ 26 | taction.c \ 27 | sigtrap.c \ 28 | message.c \ 29 | cmd-common.c \ 30 | cmd-install.c \ 31 | cmd-remove.c \ 32 | cmd-upgrade.c \ 33 | cmd-list.c 34 | 35 | # Library build reciepe 36 | libspkg_a_SOURCES = $(SPKG_LIB_SRC) 37 | spkg_SOURCES = main.c 38 | spkg_LDADD = libspkg.a -lpopt $(GLIB_LIBS) -lJudy -lz 39 | 40 | # Build only static spkg as spkg 41 | if STATIC_SPKG_ONLY 42 | 43 | bin_PROGRAMS = spkg 44 | noinst_LIBRARIES = libspkg.a 45 | spkg_LDFLAGS = -all-static 46 | 47 | else 48 | 49 | # Build spkg.static and dynamic spkg binaries 50 | if STATIC_SPKG 51 | 52 | bin_PROGRAMS = spkg spkg.static 53 | lib_LIBRARIES = libspkg.a 54 | 55 | spkg_static_LDADD = $(spkg_LDADD) 56 | spkg_static_SOURCES = main.c 57 | spkg_static_LDFLAGS = -all-static 58 | 59 | else 60 | # Build dynamic spkg binary 61 | 62 | bin_PROGRAMS = spkg 63 | lib_LIBRARIES = libspkg.a 64 | 65 | endif 66 | 67 | endif 68 | -------------------------------------------------------------------------------- /docs/web/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: "Arial CE", Arial, Helvetica, sans-serif; 3 | margin: 0; 4 | padding: 0; 5 | } 6 | 7 | a { 8 | color: #00487D; 9 | text-decoration: none; 10 | } 11 | 12 | a:hover { 13 | text-decoration: underline; 14 | } 15 | h1 { 16 | margin: 0; 17 | padding: 0; 18 | padding-bottom: 10px; 19 | border-bottom: 1px solid black; 20 | } 21 | h1 span.title { 22 | color: #0066B3; 23 | } 24 | h1 span.subtitle { 25 | font-size: 70%; 26 | } 27 | h2 { 28 | } 29 | code { 30 | display: block; 31 | border: 1px dashed #00487D; 32 | color: #00487D; 33 | background-color: #F7FEFF; 34 | display: block; 35 | padding: 10px; 36 | } 37 | img { 38 | border: 0; 39 | } 40 | /*********************/ 41 | #all { 42 | border-top: 20px solid #00487D; 43 | border-bottom: 20px solid #00487D; 44 | padding: 20px; 45 | width: 700px; 46 | margin-left: auto; 47 | margin-right: auto; 48 | background-color: #E6EDF2; 49 | } 50 | /*********************/ 51 | #topmenu { 52 | padding-top: 10px; 53 | font-weight: bold; 54 | } 55 | #botmenu { 56 | border-top: 1px solid black; 57 | padding-top: 10px; 58 | text-align: center; 59 | font-size: 70%; 60 | margin-top: 10px; 61 | } 62 | #lonmenu { 63 | border-top: 1px solid black; 64 | padding-top: 10px; 65 | text-align: center; 66 | font-size: 70%; 67 | margin-top: 10px; 68 | vertical-align: center; 69 | } 70 | -------------------------------------------------------------------------------- /docs/web/dloads.php: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Downloads

4 | 5 |

On this page you can get the lastest version of the spkg: 6 | spkg-

7 | 8 |

Binary packages

9 | 10 |

I recommend you to build spkg yourself. It's very easy as you can see 11 | below. Binary packages for linux are no longer available. Package for windows 12 | can be downloaded here: 13 | spkg--win32-bin.tar.gz.

14 | 15 |

Source code

16 | 17 |

Source code is distributed as an ordinary tarball. Tarball for 18 | the latest version is: 19 | spkg-.tar.gz.

20 | 21 |

More files

22 | 23 |

You can find more files in this directory.

24 | 25 |

Building

26 | 27 |

Prerequisites for building spkg are at least:

28 | 29 | 35 | 36 |

NOTE: It may compile/work even with older version of these libraries but it was not tested.

37 | 38 |

Installing spkg is very easy. Just extract source code package 39 | and run these commands (you will need to have Judy installed first):

40 | # ./configure && make && make install 41 | 42 |

To uninstall spkg, do:

43 | # make uninstall 44 | 45 | 46 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | This is free software. Not like beer or like in "freedom", but like in 2 | "I don't care what are you going to do with it." 3 | 4 | This work statically links following libraries: 5 | 6 | popt : a totally free library 7 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 8 | 9 | Copyright (c) 1998 Red Hat Software 10 | 11 | Permission is hereby granted, free of charge, to any person obtaining a 12 | copy of this software and associated documentation files (the 13 | "Software"), to deal in the Software without restriction, including 14 | without limitation the rights to use, copy, modify, merge, publish, 15 | distribute, sublicense, and/or sell copies of the Software, and to 16 | permit persons to whom the Software is furnished to do so, subject to 17 | the following conditions: 18 | 19 | The above copyright notice and this permission notice shall be included in 20 | all copies or substantial portions of the Software. 21 | 22 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 23 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 24 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 25 | IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR 26 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 27 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 28 | OTHER DEALINGS IN THE SOFTWARE. 29 | 30 | glib2 : partially free library 31 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 32 | 33 | Just an ordinary LGPLv2. 34 | 35 | Judy : partially free library 36 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | 38 | Just an ordinary LGPLv2.1. 39 | 40 | ------------------------------------------------------------------- 41 | | Note: It is solely your responsibility to obey all restrictions | 42 | | of LGPL. | 43 | ------------------------------------------------------------------- 44 | 45 | See COPYING in the source package of the particular library for more 46 | details. 47 | -------------------------------------------------------------------------------- /include/cmd-common.h: -------------------------------------------------------------------------------- 1 | // vim:et:sta:sts=2:sw=2:ts=2:tw=79: 2 | /*----------------------------------------------------------------------*\ 3 | |* spkg - The Unofficial Slackware Linux Package Manager *| 4 | |*----------------------------------------------------------------------*| 5 | |* No copy/usage restrictions are imposed on anybody. *| 6 | \*----------------------------------------------------------------------*/ 7 | #ifndef SPKG__CMD_COMMON_H 8 | #define SPKG__CMD_COMMON_H 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include "misc.h" 18 | #include "path.h" 19 | #include "sys.h" 20 | #include "taction.h" 21 | 22 | #include "misc.h" 23 | #include "cmd-private.h" 24 | 25 | extern gboolean _check_libc_libs(const gchar* path); 26 | 27 | extern void _run_ldconfig(const gchar* root, const struct cmd_options* opts); 28 | 29 | extern void _gtk_update_icon_cache(const gchar* root, const struct cmd_options* opts); 30 | 31 | extern gboolean _unsafe_path(const gchar* path); 32 | 33 | extern void _read_slackdesc(struct untgz_state* tgz, struct db_pkg* pkg); 34 | 35 | extern gint _read_doinst_sh(struct untgz_state* tgz, struct db_pkg* pkg, 36 | const gchar* root, const gchar* sane_path, 37 | const struct cmd_options* opts, struct error* e, 38 | const gboolean do_upgrade, struct db_pkg* ipkg); 39 | 40 | extern void _extract_file(struct untgz_state* tgz, struct db_pkg* pkg, 41 | const gchar* sane_path, const gchar* root, 42 | const struct cmd_options* opts, struct error* e, 43 | gboolean do_upgrade, struct db_pkg* ipkg); 44 | 45 | extern void _copy_douninst_sh(const gchar* pkgname, const struct cmd_options* opts, 46 | const gchar* root); 47 | 48 | extern void _run_douninst_sh(const gchar* pkgname, const struct cmd_options* opts, 49 | const gchar* root); 50 | 51 | #endif // SPKG__CMD_COMMON_H 52 | -------------------------------------------------------------------------------- /BENCHMARKS: -------------------------------------------------------------------------------- 1 | BENCHMARK no.1 2 | ============== 3 | 4 | This benchmark compares spkg with pkgtools and plain tar. 5 | 6 | Hardware setup used: 7 | 8 | CPU: Athlon Thunderbird 1GHz 9 | MEM: 512MB SDRAM 133MHz 10 | HDD1: Seagate Baracuda 7200.9 80GB 11 | HDD2: Samsung SP2002H 20GB 7200 rpm 12 | OS: 'vanilla' linux 2.6.17.2, slackware-current 13 | 14 | Benchmarking methods: 15 | 16 | Before each 'install' benchmark clean ext2 filesystem will be created on 17 | HDD2 using following command: 18 | mke2fs /dev/hdb 19 | 20 | Before each benchmarks caches will be flushed using: 21 | echo 2 > /proc/sys/vm/drop_caches 22 | 23 | All services that could affect result of benchmarks will be stopped. 24 | 25 | Install speed 26 | ~~~~~~~~~~~~~ 27 | Install/extract all official slackware-current (2006-07-11) packages 28 | from the installation packages on HDD1 to the root directory on HDD2. 29 | 30 | 1) 31 | spkg -r /data -i */*.tgz 32 | 33 | 2) 34 | installpkg -root /data */*.tgz 35 | 36 | 3) 37 | for f in */*.tgz ; do 38 | tar xf $f -C /data 39 | done 40 | 41 | Remove speed 42 | ~~~~~~~~~~~~ 43 | Remove all 'kde*' packages from the system. ;-) 44 | 45 | 1) 46 | spkg -r /data -d `spkg -r /data -l 'kde*'` 47 | 48 | 2) 49 | ROOT=/data removepkg `spkg -r /data -l 'kde*'` 50 | 51 | Results 52 | ~~~~~~~ 53 | 54 | Install speed: 55 | 1) real 12m 36s, user 2m 3s, sys 51s 56 | 2) real 23m 41s, user 15m 31s, 5m 28s 57 | 3) real 13m 17s, user 1m 46s, sys 56s 58 | 59 | Remove speed: 60 | 1) real 1m 29s, user 3.4s, sys 3.9s 61 | 2) real 27m 49s, user 19m 46s, sys 6m 30s 62 | 63 | BENCHMARK no.2 64 | ============== 65 | 66 | Install Slackware 10.1.0 67 | 68 | cmd: ipkg -r /root {a,ap,d,l,n}/*.tgz 69 | time: 3m41s, 54s, 38s 70 | 71 | cmd: installpkg -root /root {a,ap,d,l,n}/*.tgz 72 | time: 16m4s, 7m42s, 3m11s 73 | 74 | Upgrade to Slackware 10.2.0 75 | 76 | cmd: upkg -r /root {a,ap,d,l,n}/*.tgz 77 | time: 4m39s, 0m50s, 0m40s 78 | 79 | cmd: ROOT=/root upgradepkg {a,ap,d,l,n}/*.tgz 80 | time: 33m50s, 18m30s, 6m45s 81 | 82 | Remove d series packages 83 | 84 | cmd: ROOT=/root removepkg `cat d-list` 85 | time: 6m6s, 3m43s, 1m3s 86 | 87 | cmd: rpkg -r /root `cat pkglist` 88 | time: 11.8s, 0.67s, 1.18s 89 | -------------------------------------------------------------------------------- /docs/web/index.php: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Welcome to the official website of spkg, the unofficial Slackware Linux package manager. spkg 5 | is implemented in C and optimized for speed. The latest version 6 | relased on is: 7 | spkg-. See NEWS 8 | file for more information about this release.

9 | 10 |

Spkg is used in Salix OS to 11 | make its package installation and upgrades blazingly fast.

12 | 13 |

News

14 | 15 |

Spkg 1.0 was released

16 | 17 |

After almost five years since the development started, spkg reached version 1.0. Yay!

18 | 19 |

Over those five years, spkg received some commercial support by Zonio, 20 | gained windows support thanks to Laura Michaels, 21 | and was adopted by Salix OS developers for package management in their 22 | distribution.

23 | 24 |

Spkg GIT repository on GITHUB

25 | 26 |

Spkg GIT repository is available on GITHUB. Feel free to 28 | create forks and send me pull requests. ;-)

29 | 30 |

See older news...

31 | 32 |

Features

33 | 34 |
    35 |
  • Simple user interface. Just like pkgtools.
  • 36 |
  • Fast install, upgrade and remove operations.
  • 37 |
  • Command to list information about installed packages.
  • 38 |
  • Dry-run mode, in which filesystem is not touched.
  • 39 |
  • Safe mode for installing untrusted packages.
  • 40 |
  • Rollback and safe cancel functionality.
  • 41 |
  • You can use spkg and pkgtools side by side.
  • 42 |
  • You can be informed about all actions spkg does if you turn on verbose mode.
  • 43 |
  • Everything is libified. (see docs) You can 44 | implement new commands easily.
  • 45 |
46 | 47 |

You can find some benchmarks here. Here are 48 | just a few numbers 49 | comparing pkgtools to spkg: installation is at least 4x faster, 50 | upgrade is 7x faster and remove is 30x faster on averange.

51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | --------------------------------------------------------------------- 2 | before 1.0 | 3 | -----------/ 4 | 5 | - segfault on SIG in static binary 6 | 7 | 1. When upgrading, spkg may accidently delete files from the new package 8 | install because of the symlinked directory issue - say docs were installed 9 | to /usr/share/doc/$name, but the new packages installs them to 10 | /usr/doc/$name. One way to fix it is by reiterating the list of installed 11 | files before doinst.sh is run, and reinstall files if they do not exist. 12 | (What pkgtools does is install the package again as a third step unless 13 | "-no-paranoia" is set). 14 | 15 | This will require path normalization for package database and some hacks 16 | to make it work even with broken package databases. (or just that hack) 17 | 18 | 2. Another issue with upgrading is that when the new package is corrupt or 19 | unacceptable for some reason (say, tar is containing symlinks), the script 20 | at var/log/scripts of the old package is still renamed to the new package 21 | name. (this may be false report) 22 | 23 | [test] Automatic testuite 24 | 25 | [doc] Update documentation 26 | [doc] Write article 27 | 28 | Spkg 1.0 should have somewhere a list of important differences in 29 | behaviour from official pkgtools. Here's a short list: 30 | 31 | 1. spkg does not support the -preserve or -copy options of removepkg. 32 | 2. When spkg cannot overwrite a file during install/upgrade it keeps a 33 | copy as $(name)-##$(operation)## 34 | 3. spkg will not allow installing several different version of a package 35 | at the same system. 36 | 4. The errorlevels given by installpkg and spkg -i are incompatible. 37 | 5. installpkg allows non-root user to install as long as they have 38 | write access to the database. 39 | 6. Because pkgtools use gzip, a .tgz file doesn't have to be a .tar.gz 40 | file to work. .tar.Z or .tar.zip, if renamed to .tgz will work just as 41 | well. 42 | 43 | --------------------------------------------------------------------- 44 | post 1.0 | 45 | ---------/ 46 | 47 | list files that can't be removed in removed_packages/package.leftovers ??? 48 | -- why not just do grep on output from spkg? 49 | spkg -d --copy=dir package ??? 50 | - --verify command for checking fs against package database (what files 51 | changed after installation, missing files, etc.) 52 | - --check command for checking validity of slack packages 53 | (check for suid binaries and other rights based checks for files, 54 | enforcing slackware packages policy) 55 | 56 | [untgz] using blockbuf as writebuf can speedup things slightly on the 57 | user side (approx. by some 5%) 58 | 59 | extend install/doinst.sh: 60 | 61 | exit 0 62 | #!REMOVE! 63 | code 64 | code 65 | code (until next block or end) 66 | #!UPGRADE! 67 | code 68 | code 69 | code 70 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | AC_PREREQ([2.68]) 2 | AC_INIT([spkg], [1.8], [vlahavas@gmail.com]) 3 | AC_CONFIG_SRCDIR([config.h.in]) 4 | AC_CONFIG_HEADERS([config.h]) 5 | AC_CONFIG_MACRO_DIR([m4]) 6 | 7 | # Checks for programs. 8 | AC_PROG_AWK 9 | AC_PROG_CC 10 | AC_PROG_CPP 11 | AC_PROG_INSTALL 12 | AC_PROG_LN_S 13 | AC_PROG_MAKE_SET 14 | AC_PROG_RANLIB 15 | 16 | # Checks for libraries. 17 | AC_CHECK_LIB(Judy, [Judy1Next], [true], AC_MSG_ERROR([spkg requires Judy: http://judy.sf.net])) 18 | AC_CHECK_LIB(z, [compress], [true], AC_MSG_ERROR([spkg requires zlib: http://www.zlib.net])) 19 | AC_CHECK_LIB(popt, [poptGetArg], [true], AC_MSG_ERROR([spkg requires popt library])) 20 | 21 | # Checks for header files. 22 | AC_CHECK_HEADERS([fcntl.h limits.h stdlib.h string.h sys/file.h unistd.h utime.h]) 23 | AC_CHECK_HEADER([Judy.h], [true], AC_MSG_ERROR([spkg requires Judy: http://judy.sf.net])) 24 | AC_CHECK_HEADER([zlib.h], [true], AC_MSG_ERROR([spkg requires zlib: http://www.zlib.net])) 25 | AC_CHECK_HEADER([popt.h], [true], AC_MSG_ERROR([spkg requires popt library])) 26 | 27 | # Checks for pkg-config packages 28 | PKG_CHECK_MODULES(GLIB, [glib-2.0 >= 2.2.0]) 29 | AC_SUBST(GLIB_CFLAGS) 30 | AC_SUBST(GLIB_LIBS) 31 | 32 | # Checks for typedefs, structures, and compiler characteristics. 33 | AC_TYPE_UID_T 34 | AC_TYPE_MODE_T 35 | AC_TYPE_OFF_T 36 | AC_TYPE_SIZE_T 37 | AC_TYPE_SSIZE_T 38 | AC_CHECK_MEMBERS([struct stat.st_rdev]) 39 | 40 | # Checks for library functions. 41 | AC_FUNC_CHOWN 42 | AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK 43 | AC_FUNC_REALLOC 44 | AC_CHECK_FUNCS([getdelim memset mkdir mkfifo putenv rmdir strchr strerror utime]) 45 | 46 | # Automake 47 | AM_INIT_AUTOMAKE([dist-bzip2]) 48 | AM_MAINTAINER_MODE 49 | m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) 50 | 51 | # Assume broken pkgdb 52 | AC_ARG_ENABLE(assume-broken-pkgdb,AC_HELP_STRING([--enable-assume-broken-pkgdb], 53 | [Compile with support for broken package databases that may contain 54 | non-normalized paths with multiple slashes. This doubles time necessary to load 55 | file database. To see if you need to enable this option, check paths in your 56 | package database with 'grep // /var/lib/pkgtools/packages/*' command.])) 57 | 58 | AM_CONDITIONAL(ENABLE_ASSUME_BROKEN_PKGDB, test "x$enable_assume_broken_pkgdb" = xyes) 59 | 60 | # Static spkg 61 | AC_ARG_ENABLE(static-spkg, 62 | AS_HELP_STRING([--enable-static-spkg], 63 | [Create static spkg executable. Use --enable-static-spkg=only for 64 | creating only static spkg binary that will be used by default.]), 65 | [create_static=$enableval], [create_static=no]) 66 | 67 | AM_CONDITIONAL([STATIC_SPKG],[test "x$create_static" = "xyes"]) 68 | AM_CONDITIONAL([STATIC_SPKG_ONLY],[test "x$create_static" = "xonly"]) 69 | 70 | AC_ARG_ENABLE(legacy, 71 | AS_HELP_STRING([--disable-legacy], 72 | [Disable legacy checks, like symlinks in the archive. (EXPERIMENTAL)]), 73 | [legacy_checks=$enableval], [legacy_checks=yes]) 74 | 75 | AM_CONDITIONAL([LEGACY_CHECKS],[test x$legacy_checks = xyes]) 76 | 77 | # Output 78 | AC_CONFIG_FILES([ 79 | Makefile 80 | src/Makefile 81 | include/Makefile 82 | docs/Makefile 83 | tests/Makefile 84 | libspkg.pc 85 | ]) 86 | AC_OUTPUT 87 | -------------------------------------------------------------------------------- /docs/web/history.php: -------------------------------------------------------------------------------- 1 | 2 | 3 |

History

4 | 5 |

2006-07-17

6 |
    7 |
  • Spkg is feature complete!
  • 8 |
  • Less screwed website design.
  • 9 |
  • Upgrade command implemented. It is not tested very much. 10 | I've just tested it on the samba package from the slackware 11 | current and it works same as upgradepkg from pkgtools. 12 | It's based on the cmd_install() code though, so it should 13 | work quit well. Time will tell.
  • 14 |
  • Install command refactoring: cmd_install() was split into 15 | smaller and easilly manageable functions.
  • 16 |
  • Memory allocation audit. (confirmed by valgrind and glib 17 | memory allocation profiler)
  • 18 |
  • Root path sanitization. (fixes double slashes when --root /)
  • 19 |
  • Improved and more consistent output from commands.
  • 20 |
  • Added more warnings where necessary. (permission diferences 21 | between installed and existing directories, files changed 22 | after installation, etc.)
  • 23 |
  • --dry-run should be now really DRY. :)
  • 24 |
  • Perform sanity checks on paths extracted from the doinst.sh 25 | script.
  • 26 |
  • Added dep packages download script, for those who want 27 | to build static verion of the spkg and don't want to search 28 | whole day for popt-1.10.2 sources on the internet. ;-)
  • 29 |
  • Improved package name guessing algorithm.
  • 30 |
31 | 32 |

2006-07-14

33 |

I started publishing patches to the alpha1 version of spkg 34 | in the patches directory.

35 |

2006-07-10

36 |

Firtst alpha version released! This version implements install, 37 | remove and list commands. See manpage for more information. 38 | 39 | Other new features include fully functional command line interface 40 | with corresponding manpage and implementation of safe break points. 41 | 42 | You can safely break any command using some reasonable signal like 43 | SIGINT and all changes made so far will be automatically rolled back. 44 | 45 | There are new command verbosity selection options too. 46 | 47 | I've put spkg on diet and completely dropped sqlite and filedb 48 | database code. This results in fewer dependencies and little to 49 | no performance impact. Filedb code was replaced with JudySL 50 | arrays. See this page 51 | for more info. 52 | 53 | Enjoy it!

54 |

2005-07-17

55 |

Install command is nearly completed. spkg installs 60 packages 56 | (total size 18MB) under 3 seconds. Installpkg from pkgtools needs 90 57 | seconds to install the same set of packages. Whooooa! Maybe I should 58 | reabbreviate spkg for speeeeedy package manager. :] Keep tuned.

59 |

2005-06-29

60 |

Pkgdb completed.

61 |

2005-06-27

62 |

Filedb library received new features: fast distributed 63 | checksumming and per file arbitrary data storing. It is possible 64 | to open multiple file databases at once. Implemented new, much 65 | better error handling everywhere. TODO 66 | file is now automatically updated on the web.

67 |

2005-06-21

68 |

I've implemented Python 69 | bindings. Now I'm finishing pkgdb library.

70 |

2005-06-14

71 |

SQL database wrapper API completed. Untgz documented.

72 |

2005-06-12

73 |

Another milestone achieved. Pkgdb is fast. Database operations on 74 | averange package can be done in 2ms on my 1GHz Athlon. Full 75 | synchronization with legacy database on my system can be done in 1 second. 76 | (522 packages)

77 |

2005-06-10

78 |

Website created. Development code released.

79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /docs/spkg.8: -------------------------------------------------------------------------------- 1 | .TH SPKG 8 "June 2022" "spkg" 2 | .SH NAME 3 | spkg \- The Unofficial \fISlackware Linux\fR Package Manager 4 | .SH SYNOPSIS 5 | .B spkg 6 | [\fB-i\fR|\fB--install\fR] 7 | [\fB-u\fR|\fB--upgrade\fR] 8 | [\fB-d\fR|\fB--remove\fR] 9 | [\fB-l\fR|\fB--list\fR] 10 | [\fB--root\fR \fIROOT\fR] 11 | [\fB-p\fR|\fB--purge\fR] 12 | [\fB-n\fR|\fB--dry-run\fR] 13 | [\fB-s\fR|\fB--safe\fR] 14 | [\fB--reinstall\fR] 15 | [\fB--install-new\fR] 16 | [\fB--no-fast-symlinks\fR] 17 | [\fB--no-scripts\fR] 18 | [\fB--no-ldconfig\fR] 19 | [\fB--no-gtk-update-icon-cache\fR] 20 | [\fB-q\fR|\fB--quiet\fR] 21 | [\fB-v\fR|\fB--verbose\fR] 22 | [\fIpackages...\fR] 23 | .CM =========================================================================== 24 | .SH DESCRIPTION 25 | \fBspkg\fR is a fast and robust tool for \fISlackware Linux\fR package management. 26 | .CM =========================================================================== 27 | .SH COMMAND LINE ARGUMENTS 28 | .SS Commands 29 | .TP 30 | \fB-i\fR, \fB--install\fR 31 | Install given packages. 32 | .TP 33 | \fB-u\fR, \fB--upgrade\fR 34 | Upgrade given packages. 35 | .TP 36 | \fB-d\fR, \fB--remove\fR 37 | Remove given packages. You may use shortname, full name or package file name 38 | to specify packages to be removed. 39 | .TP 40 | \fB-l\fR, \fB--list\fR 41 | List names of all installed packages. You may use -v option to show package 42 | details too. Adding package shortname on the command line will make list 43 | limited to that specific packages. You may use glob matching to specify 44 | package names. For example to list all kde packages use 'spkg -l *kde*'. 45 | .CM =========================================================================== 46 | .SS Options 47 | .TP 48 | \fB--root=\fIROOT\fR 49 | Set alternate root directory for package operations. You can also use ROOT 50 | environment variable. (default: "/") 51 | .TP 52 | \fB-v\fR | \fB--verbose\fR 53 | Increase verbosity level. When used once, files and 54 | directories that are affected by particular operation 55 | will be shown. When used twice, everything that is 56 | done will be reported. 57 | .TP 58 | \fB-q\fR | \fB--quiet\fR 59 | Decrease verbosity level. Default is to show info 60 | messages and warnings. This option disables warnings 61 | when used once. When used twice it will completely 62 | disable output except for error messages. 63 | .TP 64 | \fB-p\fR | \fB--purge\fR 65 | When removing a package, purge configuration files from the system. 66 | Configuration files usually come with a ".new" suffix. When they are 67 | processed during installation, the ".new" suffix is removed. The 68 | processed files are not included in the package lists. By using this 69 | option, the processed configuration files are also removed from the 70 | system. 71 | .TP 72 | \fB-n\fR | \fB--dry-run\fR 73 | Don't modify filesystem or database. This may be useful when used along 74 | with -v option to check what exactly would given command do. 75 | .TP 76 | \fB-s\fR | \fB--safe\fR 77 | Play it safe. Don't replace existing files during --install or --upgrade. 78 | Don't run post-installation scripts. Don't remove changed files on 79 | --remove. 80 | .TP 81 | \fB--reinstall\fR | \fB-reinstall\fR 82 | When upgrading package and package already exists in the database, 83 | force reinstall. 84 | .TP 85 | \fB--install-new\fR 86 | When upgrading package that does not yet exist in the database, 87 | install it instead. 88 | .TP 89 | \fB--no-fast-symlinks\fR 90 | Spkg by default parses doinst.sh for symlink creation code and removes 91 | it from the script. This improves execution times of doinst.sh. Use 92 | this option to disable such optimizations. 93 | .TP 94 | \fB--no-scripts\fR 95 | Disable postinstallation script. 96 | .TP 97 | \fB--no-ldconfig\fR 98 | Don't execute ldconfig after installation and upgrade. 99 | .TP 100 | \fB--no-gtk-update-icon-cache\fR 101 | When a package includes a .desktop file, in other words when a package 102 | includes a menu entry, spkg by default runs gtk-update-icon-cache, so 103 | that the icon cache will be updated, ensuring that the menu icon will 104 | be displayed properly at all times. Using this option, this behaviour 105 | is disabled. Useful if you want to install a large number of packages 106 | that include menu entries; installation will be faster without updating 107 | the icon cache after installing every package. The user could run 108 | gtk-update-icon-cache manually after all packages have been installed. 109 | .CM =========================================================================== 110 | .SS Help 111 | .TP 112 | \fB--usage\fR 113 | Display brief usage message. 114 | .TP 115 | \fB-h\fR, \fB--help\fR 116 | Show long help. 117 | .TP 118 | \fB-V\fR, \fB--version\fR 119 | Display spkg version. 120 | .CM =========================================================================== 121 | .SH FILES 122 | .IP "/var/lib/pkgtools/{packages,scripts}" 123 | Package database. 124 | .SH EXAMPLES 125 | .TP 126 | spkg -i [--install] 127 | .TP 128 | spkg -dv [--remove --verbose] 129 | .TP 130 | spkg -u [--upgrade] 131 | .TP 132 | spkg -uvn [--upgrade --verbose --dry-run] 133 | .SH AUTHOR 134 | Written by Ondrej Jirman, 2005-2006. Maintained by George Vlahavas 135 | 2012-2022. 136 | .TP 137 | Official website: http://spkg.megous.com 138 | .SH BUGS 139 | Bug reports can be sent to . 140 | .SH SEE ALSO 141 | .BR installpkg (8), 142 | .BR removepkg (8), 143 | .BR upgradepkg (8) 144 | -------------------------------------------------------------------------------- /docs/devel/Doxyfile: -------------------------------------------------------------------------------- 1 | # Doxyfile 1.4.7 2 | 3 | #--------------------------------------------------------------------------- 4 | # Project related configuration options 5 | #--------------------------------------------------------------------------- 6 | PROJECT_NAME = $(PROJECT) 7 | PROJECT_NUMBER = $(VERSION) 8 | OUTPUT_DIRECTORY = $(OUTDIR) 9 | CREATE_SUBDIRS = NO 10 | OUTPUT_LANGUAGE = English 11 | USE_WINDOWS_ENCODING = NO 12 | BRIEF_MEMBER_DESC = YES 13 | REPEAT_BRIEF = YES 14 | ABBREVIATE_BRIEF = 15 | ALWAYS_DETAILED_SEC = YES 16 | INLINE_INHERITED_MEMB = NO 17 | FULL_PATH_NAMES = NO 18 | STRIP_FROM_PATH = $(SRCDIR)/include/ 19 | STRIP_FROM_INC_PATH = 20 | SHORT_NAMES = NO 21 | JAVADOC_AUTOBRIEF = YES 22 | MULTILINE_CPP_IS_BRIEF = NO 23 | DETAILS_AT_TOP = YES 24 | INHERIT_DOCS = YES 25 | SEPARATE_MEMBER_PAGES = YES 26 | TAB_SIZE = 4 27 | ALIASES = 28 | OPTIMIZE_OUTPUT_FOR_C = YES 29 | OPTIMIZE_OUTPUT_JAVA = NO 30 | BUILTIN_STL_SUPPORT = NO 31 | DISTRIBUTE_GROUP_DOC = NO 32 | SUBGROUPING = YES 33 | #--------------------------------------------------------------------------- 34 | # Build related configuration options 35 | #--------------------------------------------------------------------------- 36 | EXTRACT_ALL = NO 37 | EXTRACT_PRIVATE = NO 38 | EXTRACT_STATIC = NO 39 | EXTRACT_LOCAL_CLASSES = YES 40 | EXTRACT_LOCAL_METHODS = NO 41 | HIDE_UNDOC_MEMBERS = NO 42 | HIDE_UNDOC_CLASSES = NO 43 | HIDE_FRIEND_COMPOUNDS = NO 44 | HIDE_IN_BODY_DOCS = NO 45 | INTERNAL_DOCS = NO 46 | CASE_SENSE_NAMES = YES 47 | HIDE_SCOPE_NAMES = NO 48 | SHOW_INCLUDE_FILES = YES 49 | INLINE_INFO = YES 50 | SORT_MEMBER_DOCS = NO 51 | SORT_BRIEF_DOCS = NO 52 | SORT_BY_SCOPE_NAME = NO 53 | GENERATE_TODOLIST = YES 54 | GENERATE_TESTLIST = YES 55 | GENERATE_BUGLIST = YES 56 | GENERATE_DEPRECATEDLIST= YES 57 | ENABLED_SECTIONS = 58 | MAX_INITIALIZER_LINES = 30 59 | SHOW_USED_FILES = YES 60 | SHOW_DIRECTORIES = YES 61 | FILE_VERSION_FILTER = 62 | #--------------------------------------------------------------------------- 63 | # configuration options related to warning and progress messages 64 | #--------------------------------------------------------------------------- 65 | QUIET = YES 66 | WARNINGS = YES 67 | WARN_IF_UNDOCUMENTED = YES 68 | WARN_IF_DOC_ERROR = YES 69 | WARN_NO_PARAMDOC = NO 70 | WARN_FORMAT = "$file:$line: $text" 71 | WARN_LOGFILE = 72 | #--------------------------------------------------------------------------- 73 | # configuration options related to the input files 74 | #--------------------------------------------------------------------------- 75 | INPUT = $(SRCDIR)/include \ 76 | $(SRCDIR)/docs/devel 77 | FILE_PATTERNS = *.h \ 78 | *.doc 79 | RECURSIVE = NO 80 | EXCLUDE = 81 | EXCLUDE_SYMLINKS = NO 82 | EXCLUDE_PATTERNS = 83 | EXAMPLE_PATH = 84 | EXAMPLE_PATTERNS = 85 | EXAMPLE_RECURSIVE = NO 86 | IMAGE_PATH = 87 | INPUT_FILTER = 88 | FILTER_PATTERNS = 89 | FILTER_SOURCE_FILES = NO 90 | #--------------------------------------------------------------------------- 91 | # configuration options related to source browsing 92 | #--------------------------------------------------------------------------- 93 | SOURCE_BROWSER = NO 94 | INLINE_SOURCES = NO 95 | STRIP_CODE_COMMENTS = YES 96 | REFERENCED_BY_RELATION = YES 97 | REFERENCES_RELATION = YES 98 | REFERENCES_LINK_SOURCE = YES 99 | USE_HTAGS = NO 100 | VERBATIM_HEADERS = YES 101 | #--------------------------------------------------------------------------- 102 | # configuration options related to the alphabetical class index 103 | #--------------------------------------------------------------------------- 104 | ALPHABETICAL_INDEX = NO 105 | COLS_IN_ALPHA_INDEX = 3 106 | IGNORE_PREFIX = 107 | #--------------------------------------------------------------------------- 108 | # configuration options related to the HTML output 109 | #--------------------------------------------------------------------------- 110 | GENERATE_HTML = YES 111 | HTML_OUTPUT = api-html 112 | HTML_FILE_EXTENSION = .html 113 | HTML_HEADER = $(SRCDIR)/docs/devel/header.html 114 | HTML_FOOTER = $(SRCDIR)/docs/devel/footer.html 115 | HTML_STYLESHEET = 116 | HTML_ALIGN_MEMBERS = YES 117 | GENERATE_HTMLHELP = NO 118 | CHM_FILE = 119 | HHC_LOCATION = 120 | GENERATE_CHI = NO 121 | BINARY_TOC = NO 122 | TOC_EXPAND = NO 123 | DISABLE_INDEX = NO 124 | ENUM_VALUES_PER_LINE = 4 125 | GENERATE_TREEVIEW = NO 126 | TREEVIEW_WIDTH = 250 127 | #--------------------------------------------------------------------------- 128 | # configuration options related to the LaTeX output 129 | #--------------------------------------------------------------------------- 130 | GENERATE_LATEX = NO 131 | LATEX_OUTPUT = latex 132 | LATEX_CMD_NAME = latex 133 | MAKEINDEX_CMD_NAME = makeindex 134 | COMPACT_LATEX = NO 135 | PAPER_TYPE = a4wide 136 | EXTRA_PACKAGES = 137 | LATEX_HEADER = 138 | PDF_HYPERLINKS = NO 139 | USE_PDFLATEX = NO 140 | LATEX_BATCHMODE = NO 141 | LATEX_HIDE_INDICES = NO 142 | #--------------------------------------------------------------------------- 143 | # configuration options related to the RTF output 144 | #--------------------------------------------------------------------------- 145 | GENERATE_RTF = NO 146 | RTF_OUTPUT = rtf 147 | COMPACT_RTF = NO 148 | RTF_HYPERLINKS = NO 149 | RTF_STYLESHEET_FILE = 150 | RTF_EXTENSIONS_FILE = 151 | #--------------------------------------------------------------------------- 152 | # configuration options related to the man page output 153 | #--------------------------------------------------------------------------- 154 | GENERATE_MAN = NO 155 | MAN_OUTPUT = man 156 | MAN_EXTENSION = .3fp 157 | MAN_LINKS = NO 158 | #--------------------------------------------------------------------------- 159 | # configuration options related to the XML output 160 | #--------------------------------------------------------------------------- 161 | GENERATE_XML = NO 162 | XML_OUTPUT = xml 163 | XML_SCHEMA = 164 | XML_DTD = 165 | XML_PROGRAMLISTING = YES 166 | #--------------------------------------------------------------------------- 167 | # configuration options for the AutoGen Definitions output 168 | #--------------------------------------------------------------------------- 169 | GENERATE_AUTOGEN_DEF = NO 170 | #--------------------------------------------------------------------------- 171 | # configuration options related to the Perl module output 172 | #--------------------------------------------------------------------------- 173 | GENERATE_PERLMOD = NO 174 | PERLMOD_LATEX = NO 175 | PERLMOD_PRETTY = YES 176 | PERLMOD_MAKEVAR_PREFIX = 177 | #--------------------------------------------------------------------------- 178 | # Configuration options related to the preprocessor 179 | #--------------------------------------------------------------------------- 180 | ENABLE_PREPROCESSING = YES 181 | MACRO_EXPANSION = NO 182 | EXPAND_ONLY_PREDEF = NO 183 | SEARCH_INCLUDES = YES 184 | INCLUDE_PATH = 185 | INCLUDE_FILE_PATTERNS = 186 | PREDEFINED = 187 | EXPAND_AS_DEFINED = 188 | SKIP_FUNCTION_MACROS = YES 189 | #--------------------------------------------------------------------------- 190 | # Configuration::additions related to external references 191 | #--------------------------------------------------------------------------- 192 | TAGFILES = 193 | GENERATE_TAGFILE = 194 | ALLEXTERNALS = NO 195 | EXTERNAL_GROUPS = YES 196 | PERL_PATH = /usr/bin/perl 197 | #--------------------------------------------------------------------------- 198 | # Configuration options related to the dot tool 199 | #--------------------------------------------------------------------------- 200 | CLASS_DIAGRAMS = YES 201 | HIDE_UNDOC_RELATIONS = YES 202 | HAVE_DOT = NO 203 | CLASS_GRAPH = YES 204 | COLLABORATION_GRAPH = YES 205 | GROUP_GRAPHS = YES 206 | UML_LOOK = NO 207 | TEMPLATE_RELATIONS = NO 208 | INCLUDE_GRAPH = YES 209 | INCLUDED_BY_GRAPH = YES 210 | CALL_GRAPH = NO 211 | CALLER_GRAPH = NO 212 | GRAPHICAL_HIERARCHY = YES 213 | DIRECTORY_GRAPH = YES 214 | DOT_IMAGE_FORMAT = png 215 | DOT_PATH = 216 | DOTFILE_DIRS = 217 | MAX_DOT_GRAPH_WIDTH = 1024 218 | MAX_DOT_GRAPH_HEIGHT = 1024 219 | MAX_DOT_GRAPH_DEPTH = 0 220 | DOT_TRANSPARENT = NO 221 | DOT_MULTI_TARGETS = NO 222 | GENERATE_LEGEND = YES 223 | DOT_CLEANUP = YES 224 | #--------------------------------------------------------------------------- 225 | # Configuration::additions related to the search engine 226 | #--------------------------------------------------------------------------- 227 | SEARCHENGINE = NO 228 | -------------------------------------------------------------------------------- /src/cmd-remove.c: -------------------------------------------------------------------------------- 1 | // vim:et:sta:sts=2:sw=2:ts=2:tw=79: 2 | /*----------------------------------------------------------------------*\ 3 | |* spkg - The Unofficial Slackware Linux Package Manager *| 4 | |* designed by Ondøej Jirman, 2005 *| 5 | |*----------------------------------------------------------------------*| 6 | |* No copy/usage restrictions are imposed on anybody. *| 7 | \*----------------------------------------------------------------------*/ 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | #include "sys.h" 16 | #include "path.h" 17 | #include "cmd-private.h" 18 | #include "cmd-common.h" 19 | 20 | /* private 21 | ************************************************************************/ 22 | 23 | #define e_set(n, fmt, args...) e_add(e, "remove", __func__, n, fmt, ##args) 24 | 25 | /* purge configuration files from the system. Processed configuration files 26 | * have their .new suffix removed and don't appear in the package list. So, 27 | * remove the .new suffix and try to remove that file */ 28 | static void _purge(gchar* root, gchar* path) 29 | { 30 | gint path_len = strlen(path); 31 | /* only run this for .new files */ 32 | if (path_len > 4 && !strcmp(path + path_len - 4, ".new")) 33 | { 34 | /* strip the .new suffix */ 35 | gchar* path_processed = g_strdup_printf("%.*s", path_len - 4, path); 36 | gchar* fullpath = g_strdup_printf("%s%s", root, path_processed); 37 | 38 | struct stat st; 39 | sys_ftype type = sys_file_type_stat(fullpath, 0, &st); 40 | if (type == SYS_ERR) 41 | { 42 | _warning("File type check failed, assuming file does not exist. (%s)", path_processed); 43 | type = SYS_NONE; 44 | } 45 | /* Since this is a processed configuration file, it will not appear in the 46 | * current package's list. But if it appears in another package's list, 47 | * then it should not be removed. */ 48 | gint refs = db_filelist_get_path_refs(path_processed); 49 | if (refs > 0) 50 | { 51 | _notice("Not purging file %s (used by another package)", path_processed); 52 | } 53 | else 54 | { 55 | /* OK, let's go on to remove it */ 56 | if (type == SYS_DIR) 57 | { 58 | _warning("Expecting file, but getting directory. (%s)", path_processed); 59 | } 60 | else if (type == SYS_NONE) 61 | { 62 | _warning("File was already removed. (%s)", path_processed); 63 | } 64 | else 65 | { 66 | _notice("Purging file %s", path_processed); 67 | if (unlink(fullpath) < 0) 68 | _warning("Can't purge file %s. (%s)", path_processed, strerror(errno)); 69 | } 70 | } 71 | g_free(path_processed); 72 | g_free(fullpath); 73 | } 74 | } 75 | 76 | /* public 77 | ************************************************************************/ 78 | 79 | gint cmd_remove(const gchar* pkgname, const struct cmd_options* opts, struct error* e) 80 | { 81 | g_assert(pkgname != 0); 82 | g_assert(opts != 0); 83 | g_assert(e != 0); 84 | 85 | gchar path[MAXPATHLEN]; 86 | 87 | /* 88 | - load package from db 89 | - load list of all installed paths 90 | - copies the douninst.sh script (if it exists) to /var/tmp/spkg 91 | - remove files that has ref == 1 92 | - remove symlinks that has ref == 1 93 | - remove dirs that has ref == 1 94 | - update list of all installed files 95 | - update package database: remove package desc 96 | - run the douninst.sh script 97 | */ 98 | 99 | msg_setup(opts->verbosity); 100 | 101 | _safe_breaking_point(err0); 102 | 103 | /* get package from database */ 104 | gchar* real_pkgname = db_get_package_name(pkgname); 105 | if (real_pkgname == NULL) 106 | { 107 | e_set(E_ERROR|CMD_NOTEX, "Package not found. (%s)", pkgname); 108 | goto err0; 109 | } 110 | 111 | _inform("Removing package %s...", real_pkgname); 112 | 113 | struct db_pkg* pkg = db_get_pkg(real_pkgname, DB_GET_FULL); 114 | if (pkg == NULL) 115 | { 116 | e_set(E_ERROR|CMD_NOTEX, "Can't get package from the database. (%s)", real_pkgname); 117 | goto err1; 118 | } 119 | 120 | /* we will need filelist, so get it if it is not already loaded */ 121 | _debug("Loading list of all installed files..."); 122 | if (db_filelist_load(FALSE)) 123 | { 124 | e_set(E_ERROR, "Can't load list of all installed files."); 125 | goto err1; 126 | } 127 | 128 | _safe_breaking_point(err2); 129 | 130 | gchar* root = sanitize_root_path(opts->root); 131 | 132 | /* copy the douninst.sh script to /var/tmp/spkg/ */ 133 | _copy_douninst_sh(real_pkgname, opts, root); 134 | 135 | _debug("Removing files..."); 136 | 137 | gint* ptype; 138 | strcpy(path, ""); 139 | JSLF(ptype, pkg->paths, path); 140 | while (ptype != NULL) 141 | { 142 | if (*ptype != DB_PATH_FILE) 143 | goto skip1; 144 | 145 | /* skip paths we don't want to remove */ 146 | if (!strcmp(path, "install") ||!strncmp(path, "install/", 8) || !strcmp(path, ".")) 147 | goto skip1; 148 | 149 | gchar* fullpath = g_strdup_printf("%s%s", root, path); 150 | struct stat st; 151 | sys_ftype type = sys_file_type_stat(fullpath, 0, &st); 152 | if (type == SYS_ERR) 153 | { 154 | _warning("File type check failed, assuming file does not exist. (%s)", path); 155 | type = SYS_NONE; 156 | } 157 | 158 | gint refs = db_filelist_get_path_refs(path); 159 | if (refs == 0) 160 | { 161 | _warning("File is in the package but not in the filelist. (%s)", path); 162 | } 163 | else if (refs == 1) 164 | { 165 | if (type == SYS_DIR) 166 | { 167 | _warning("Expecting file, but getting directory. (%s)", path); 168 | } 169 | else if (type == SYS_NONE) 170 | { 171 | _warning("File was already removed. (%s)", path); 172 | if (opts->purge) 173 | _purge(root, path); 174 | } 175 | else 176 | { 177 | if (st.st_mtime > pkg->time) 178 | { 179 | _warning("File was changed after installation. (%s)", path); 180 | if (opts->safe) 181 | goto skip1_free; 182 | } 183 | _notice("Removing file %s", path); 184 | if (!opts->dryrun) 185 | { 186 | if (unlink(fullpath) < 0) 187 | _warning("Can't remove file %s. (%s)", path, strerror(errno)); 188 | if (opts->purge) 189 | _purge(root, path); 190 | } 191 | } 192 | } 193 | else 194 | { 195 | _notice("Keeping file %s (used by another package)", path); 196 | } 197 | 198 | skip1_free: 199 | g_free(fullpath); 200 | 201 | skip1: 202 | JSLN(ptype, pkg->paths, path); 203 | } 204 | 205 | _debug("Removing symlinks..."); 206 | 207 | strcpy(path, ""); 208 | JSLF(ptype, pkg->paths, path); 209 | while (ptype != NULL) 210 | { 211 | if (*ptype != DB_PATH_SYMLINK) 212 | goto skip2; 213 | 214 | gchar* fullpath = g_strdup_printf("%s%s", root, path); 215 | sys_ftype type = sys_file_type(fullpath, 0); 216 | if (type == SYS_ERR) 217 | { 218 | _warning("File type check failed, assuming file does not exist. (%s)", path); 219 | type = SYS_NONE; 220 | } 221 | 222 | gint refs = db_filelist_get_path_refs(path); 223 | if (refs == 0) 224 | { 225 | _warning("Symlink is in the package but not in filelist. (%s)", path); 226 | } 227 | else if (refs == 1) 228 | { 229 | if (type == SYS_SYM) 230 | { 231 | _notice("Removing symlink %s", path); 232 | if (!opts->dryrun) 233 | { 234 | if (unlink(fullpath) < 0) 235 | _warning("Can't remove symlink %s. (%s)", path, strerror(errno)); 236 | } 237 | } 238 | else if (type == SYS_NONE) 239 | { 240 | _warning("Symlink was already removed. (%s)", path); 241 | } 242 | else 243 | { 244 | _warning("Expecting symlink, but getting something else. (%s)", path); 245 | } 246 | } 247 | else 248 | { 249 | _notice("Keeping symlink %s (used by another package)", path); 250 | } 251 | 252 | g_free(fullpath); 253 | 254 | skip2: 255 | JSLN(ptype, pkg->paths, path); 256 | } 257 | 258 | _debug("Removing directories..."); 259 | 260 | memset(path, 0xff, sizeof(path)-1); 261 | path[sizeof(path)-1] = '\0'; 262 | JSLL(ptype, pkg->paths, path); 263 | while (ptype != NULL) 264 | { 265 | if (*ptype != DB_PATH_DIR) 266 | goto skip3; 267 | 268 | /* skip paths we don't want to remove */ 269 | if (!strcmp(path, "install") ||!strncmp(path, "install/", 8) || !strcmp(path, ".")) 270 | goto skip3; 271 | 272 | gchar* fullpath = g_strdup_printf("%s%s", root, path); 273 | sys_ftype type = sys_file_type(fullpath, 0); 274 | if (type == SYS_ERR) 275 | { 276 | _warning("File type check failed, assuming file does not exist. (%s)", path); 277 | type = SYS_NONE; 278 | } 279 | 280 | gint refs = db_filelist_get_path_refs(path); 281 | if (refs == 0) 282 | { 283 | _warning("Directory is in the package but not in filelist. (%s)", path); 284 | } 285 | else if (refs == 1) 286 | { 287 | if (type == SYS_DIR) 288 | { 289 | _notice("Removing directory %s", path); 290 | if (!opts->dryrun) 291 | { 292 | if (rmdir(fullpath) < 0) 293 | _warning("Can't remove directory %s. (%s)", path, strerror(errno)); 294 | } 295 | } 296 | else if (type == SYS_NONE) 297 | { 298 | _warning("Directory was already removed. (%s)", path); 299 | } 300 | else 301 | { 302 | _warning("Expecting directory, but getting something else. (%s)", path); 303 | } 304 | } 305 | else 306 | { 307 | _notice("Keeping directory %s (used by another package)", path); 308 | } 309 | 310 | g_free(fullpath); 311 | 312 | skip3: 313 | JSLP(ptype, pkg->paths, path); 314 | } 315 | 316 | _debug("Removing package files from the list of all installed files..."); 317 | db_filelist_rem_pkg_paths(pkg); 318 | 319 | _debug("Removing package from the database..."); 320 | if (!opts->dryrun) 321 | { 322 | if (db_rem_pkg(real_pkgname)) 323 | { 324 | e_set(E_ERROR, "Can't remove package from the database. (%s)", real_pkgname); 325 | goto err2; 326 | } 327 | } 328 | 329 | /* Run the douninst.sh script */ 330 | _debug("Running douninst.sh script..."); 331 | 332 | _run_douninst_sh(real_pkgname, opts, root); 333 | 334 | g_free(root); 335 | 336 | _debug("Removal finished!"); 337 | 338 | db_free_pkg(pkg); 339 | g_free(real_pkgname); 340 | return 0; 341 | 342 | err2: 343 | db_free_pkg(pkg); 344 | err1: 345 | g_free(real_pkgname); 346 | err0: 347 | e_set(E_PASS,"Package removal failed!"); 348 | return 1; 349 | } 350 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- 1 | ---------------------------------------------------------------- 2 | spkg - Release Notes 3 | ---------------------------------------------------------------- 4 | 2017-06-07: spkg 1.1 5 | 6 | Fix breakage when upgrading the glibc-solibs package. Do not remove 7 | symlinks to critical libc libraries when upgrading. The symlinks are 8 | taken care of when the doinst.sh script is executed anyway, so there 9 | is no harm. 10 | 11 | Add support for brotli compressed packages. 12 | 13 | Some code refactoring. 14 | 15 | Remove block for package upgrades. Some packages, such as aaa_elflibs 16 | and aaa_base were blacklisted for upgrades. That goes against what 17 | pkgtools do. All blacklisting code has been removed, it should be 18 | possible to upgrade any package now. 19 | 20 | Minor fixes in manpage. 21 | 22 | I guess I'm officially the new maintainer now... ~~ George 23 | 24 | 2013-04-02: spkg 1.0.1 25 | 26 | Updated autotools, fixed issue where spkg binary was not being generated. 27 | (reported by vegaflapjack) 28 | 29 | Fixed some compiler warnings. 30 | 31 | Added better README from Yousha Aleayoub. 32 | 33 | Added pkgdb format patch from Ruarí Ødegaard, to make spkg's package database 34 | format match that of original Slackware pkgtools. 35 | 36 | 2011-03-16: spkg 1.0 37 | 38 | Added patch from George Vlahavas that implements automatic GTK+ icon cache 39 | updates. 40 | 41 | Released spkg 1.0. :) I guess it's time after almost 5 years since the 42 | development started. 43 | 44 | 2010-06-14: spkg 1.0rc13 45 | 46 | Added support for --force option. Allows to force installation of packages 47 | with the same shortname. 48 | 49 | This option when used will create problems with package ambiguity during 50 | upgrade. spkg will pick random package with given shortname for upgrade. 51 | 52 | Make sure you know what you are doing, if you choose to use this option. 53 | 54 | 2010-04-12: spkg 1.0rc12 55 | 56 | Fixed support for .txz. 57 | 58 | 2009-06-09: spkg 1.0rc11 59 | 60 | Added support for .txz packages requested by Thorsten Mühlfelder. 61 | 62 | Fixed static spkg build option. Now it actually produces a static 63 | binary. 64 | 65 | 2009-05-25: spkg 1.0rc10 66 | 67 | Spkg is now supported on windows thanks to excellent patch from 68 | Laura Michaels . 69 | 70 | ---------------------------------------------------------------- 71 | 2007-01-27: spkg 1.0rc9 72 | 73 | Implement support for uncompressed tar pacakges. 74 | 75 | Removed automatic content based compression type detection. 76 | Compression is now determined using package suffix. Supported 77 | suffixes are: 78 | 79 | .tgz Gzip compressed package. 80 | .tlz Lzma compressed package. 81 | .tar Uncompressed package. 82 | 83 | ---------------------------------------------------------------- 84 | 2006-11-04: spkg 1.0rc8 85 | 86 | Another set of bugfixes and small features. 87 | 88 | "ROOT=" is now interpreted as "ROOT=/". Use "ROOT=." if you want to 89 | install package into current directory. (suggested by Yair K) 90 | 91 | Spkg configuration files directory is not fixed on /etc/spkg, but it 92 | can be changed using --sysconfdir option to configure script. Using 93 | --sysconfdir=/etc means that spkg will try to find configuration files 94 | in /etc/spkg. 95 | 96 | spkg.SlackBuild was improved a bit. Added slack-required file and 97 | ARCH variable, that can be overriden from environment. 98 | 99 | Fixed "Can't access package database directory." error when package 100 | directory path component contains smylink. 101 | 102 | Added --disable-legacy configure option to enable new experimental 103 | stuff. 104 | 105 | Implement support for symlinks directly in tgz archive. 106 | 107 | ---------------------------------------------------------------- 108 | 2006-09-02: spkg 1.0rc7 109 | 110 | "When one talks of having finally catched all of the bugs, another 111 | one will pop up immediately." 112 | 113 | Fixed 64bit incompatible pointer size related crashes on 64bit 114 | paltform. (pointed out, debugged and tested by Yair K) 115 | 116 | Don't build .so library until someone actually want to use it and 117 | until I stop breaking binary compatibility with each new rc release. 118 | 119 | Implement simple user interface to the most common command. 'spkg -u 120 | --install-new package' can be now executed simply as 'spkg package'. 121 | I've also dropped support for ipkg, lpkg, upkg and rpkg commands. 122 | 123 | Implemented blacklists for otpimized symlinks functionality and 124 | package upgrade. You may create /etc/spkg/upgrade_blacklist and 125 | /etc/spkg/symopts_blacklist to disallow upgrade of some packages. 126 | If you don't have these files, default blacklists will be used. 127 | 128 | Incorporated some other changes kindly suggested by Yair K: 129 | - [PATCH] Limit slack-desc to 13 lines, not 11. 130 | - Change permissions on installed directories if directory already 131 | exist. Just like pkgtools. 132 | - Don't cancel operation in safe mode if installed directory already 133 | exist on the filesytem but is hidden behind symlink. Just warn, like 134 | in normal mode. 135 | - Fix problem when user can by mistake type -reinstall or -root by 136 | disabling short version of --root command line option, so that 137 | these typos do not mean --root=einstall or --root=oot. 138 | - Pass -install to the doinst.sh script just like installpkg. 139 | - Ignore . and install/ entries in file database when doing --upgrade 140 | or --remove. 141 | - Allow to set --root option via environment variable ROOT. Just like 142 | pkgtools do. 143 | 144 | And some other small changes. See ChangeLog for detailed list. 145 | 146 | ---------------------------------------------------------------- 147 | 2006-08-20: spkg 1.0rc6 148 | 149 | Fixed a lot of compiler warnings on (-Wall -Wextra level). 150 | 151 | Fixed some incompatible pointer warnings on 64bit paltforms. 152 | (thanks to Yair K) 153 | 154 | Incorporated lots of changes suggested by Yair K: 155 | - Print usage string if no command was given. 156 | - Implement readonly database access mode so that spkg doesn't 157 | create package database in dryrun mode if it does not exist. 158 | - Improve error reporting in db_query() function. Now when 159 | spkg -l fails to read package database entry, it will show 160 | it's name. 161 | - Optional compile time selectable support for broken package 162 | databases. (Created by emerde) See --enable-assume-broken-pkgdb 163 | configure option. 164 | - Catch -reinstall command line option typo. Otherwise it would 165 | mean --root=einstall. That is probably not what you user wanted 166 | in this case. 167 | - We already had support for debug level messages, but it was 168 | unused. Move some less useful messages to that debug level. 169 | In -v mode we only show list of files affected by particular 170 | command. Use -vv if you want to see everything. 171 | 172 | Now that package database can be opened in readonly mode, spkg can run 173 | under non-root user for some commands. These commands are: --list and 174 | everything else in --dry-run mode. 175 | 176 | It's month from first release candidate and everything seems to be 177 | going well. At least for me. It seems to me that 1.0 is waiting right 178 | behind the door. :) 179 | 180 | Please test this release and give some feedback if you want. If 181 | nothing goes wrong I'll rerelease this version (plus some 182 | documentation updates) as 1.0 on 2006-09-01. 183 | 184 | ---------------------------------------------------------------- 185 | 2006-08-02: spkg 1.0rc5 186 | 187 | Implemented optimization to the ldconfig. If package does not contain 188 | .so files (dynamic libraries), ldconfig will not be executed. I guess, 189 | that only one third of the slackware packages contains .so libraries. 190 | So this is quit a good thing to do performancewise. 191 | 192 | Some fixes to the build system. I've run into problems while 193 | integrating spkg into our SBO linux distribution. 194 | 195 | And there was a kind donation from Zonio s.r.o. (http://zonio.net). 196 | 197 | ---------------------------------------------------------------- 198 | 2006-07-29: spkg 1.0rc4 199 | 200 | Dropped requirement for minimum glib version down to 2.2.1, that is 201 | version that comes with Slackware 9.0. Requirement for glib >= 2.10.0 202 | was pretty tight and allowed spkg to be used only on 203 | slackware-current. Thanks goes to johnga1 for pointing this out. 204 | 205 | Added configure option for building only static version of spkg 206 | (--enable-static-spkg=only). This is what I now use for binary package 207 | on spkg.megous.com. This fixes problem that I did run into when 208 | downgrading to glib-2.2.0 to test spkg against it. That is all goes 209 | well until we add first action to the transaction, then suddenly 210 | g_slice_new0 is needed and not found in any library and spkg 211 | terminates. This happens for the first file in the installed package, 212 | and can't break anything. If file aready existed on the filesystem it 213 | will not be owerwritten when spkg is terminated by the system. No 214 | problem here. :) 215 | 216 | Anyway, spkg is now binary comaptible with any glib from 2.2.0 217 | to 2.12.x so this problem should not happen even when using 218 | dynamically linked spkg binary. 219 | 220 | ---------------------------------------------------------------- 221 | 2006-07-28: spkg 1.0rc3 222 | 223 | Ok, we are in the rc phase, but this is pretty small change 224 | code-wise, but a good to have feature. :-) 225 | 226 | Added support for .tlz (LZMA compressed) packages. You will 227 | need to have lzma program in your path for this to work, unlike 228 | traditional .tgz packages that could be installed with just only 229 | spkg.static. I forgot to mention it, but you can use configure 230 | option --enable-static-spkg to build spkg.static in adition 231 | to the ordinary dynamic executable. 232 | 233 | Dropped support for progress callback from the untar module. 234 | 235 | Don't show raw error message when upgrade fails on not installed 236 | package. 237 | 238 | ---------------------------------------------------------------- 239 | 2006-07-26: spkg 1.0rc2 240 | 241 | Build system proted to autotools. 242 | 243 | ---------------------------------------------------------------- 244 | 2006-07-20: spkg 1.0rc1 245 | 246 | This release was tested a lot. It can upgrade Slackware 10.1 to 10.2 247 | without problems. (results are the same as with pkgtools) Everything 248 | works as expected. 249 | 250 | What's new: 251 | - Spkg no longer changes permissions of already installed directories. 252 | - Implement --reinstall and --install-new options to upgrade commad. 253 | - Show information messages and warnings by default. 254 | - Add/remove some warnings to make output more readable by human. 255 | - Improve error messages and some warnings. 256 | - Added some not so important error checks. 257 | - Cleaned up package database code. 258 | - Updated API documentation. 259 | 260 | Bugfixes: 261 | - Add missing dry run check for temporary file deletion. 262 | - When printing empty slack-desc lines, check for null strings. 263 | 264 | ---------------------------------------------------------------- 265 | 2006-07-17: spkg beta 266 | 267 | What's new: 268 | - Spkg is feature complete! 269 | - Upgrade command implemented. It is not tested very much. 270 | I've just tested it on the samba package from the slackware 271 | current and it works same as upgradepkg from pkgtools. 272 | It's based on the cmd_install() code though, so it should 273 | work quit well. Time will tell. 274 | - Install command refactoring: cmd_install() was split into 275 | smaller and easilly manageable functions. 276 | - Memory allocation audit. (confirmed by valgrind and glib 277 | memory allocation profiler) 278 | - Root path sanitization. (fixes double slashes when --root /) 279 | - Improved and more consistent output from commands. 280 | - Added more warnings where necessary. (permission diferences 281 | between installed and existing directories, files changed 282 | after installation, etc.) 283 | - --dry-run should be now really DRY. :) 284 | - Perform sanity checks on paths extracted from the doinst.sh 285 | script. 286 | - Added dep packages download script, for those who want 287 | to build static verion of the spkg and don't want to search 288 | whole day for popt-1.10.2 sources on the internet. ;-) 289 | - Improved package name guessing algorithm. 290 | 291 | What's comming: 292 | - There will be refactoring of the transaction code. (it's 293 | not broken, but it's not quit readable too) 294 | - Then, I will write automated testsuite and create some really 295 | torturous packages to test as much code paths in spkg as 296 | possible. And of course I will be running spkg in my normal 297 | day to day use. 298 | - Finally I would like to update documentation and make some 299 | benchamrks on the brand new --upgrade command. 300 | - Please, keep an eye on http://spkg.megous.com/dl/patches/beta/ 301 | for patches that will fix bugs found in this beta release. 302 | I will be adding patches there as soon as each bug is fixed. 303 | To date there are no known bugs in spkg. 304 | 305 | ---------------------------------------------------------------- 306 | 2006-07-11: spkg alpha1 307 | 308 | - First release! 309 | -------------------------------------------------------------------------------- /src/cmd-common.c: -------------------------------------------------------------------------------- 1 | // vim:et:sta:sts=2:sw=2:ts=2:tw=79: 2 | /*----------------------------------------------------------------------*\ 3 | |* spkg - The Unofficial Slackware Linux Package Manager *| 4 | |*----------------------------------------------------------------------*| 5 | |* No copy/usage restrictions are imposed on anybody. *| 6 | \*----------------------------------------------------------------------*/ 7 | 8 | #include "cmd-common.h" 9 | 10 | #define e_set(n, fmt, args...) e_add(e, "common", __func__, n, fmt, ##args) 11 | 12 | /* packages that can't be optimized, until they are fixed */ 13 | 14 | /* Check for libc symlinks to libraries that are critical to running sh. If 15 | * these symlinks are removed, doinst fails to run, because sh (bash) fails to 16 | * run. Since these are recreated with ldconfig when the glibc-solibs package 17 | * is installed, it's same to leave them where they are 18 | */ 19 | gboolean _check_libc_libs(const gchar* path) 20 | { 21 | if (strncmp(path, "lib/ld-linux.so", strlen("lib/ld-linux.so")) == 0 || 22 | strncmp(path, "lib64/ld-linux-x86-64.so", strlen("lib64/ld-linux-x86-64.so")) == 0 || 23 | strncmp(path, "lib/libc.so", strlen("lib/libc.so")) == 0 || 24 | strncmp(path, "lib64/libc.so", strlen("lib64/libc.so")) == 0 || 25 | strncmp(path, "lib/libdl.so", strlen("lib/libdl.so")) == 0 || 26 | strncmp(path, "lib64/libdl.so", strlen("lib64/libdl.so")) == 0) 27 | { 28 | return 0; 29 | } 30 | return 1; 31 | } 32 | 33 | void _run_ldconfig(const gchar* root, const struct cmd_options* opts) 34 | { 35 | if (access("/sbin/ldconfig", X_OK) == 0) 36 | { 37 | gchar* ldconf_file = g_strdup_printf("%setc/ld.so.conf", root); 38 | if (access(ldconf_file, R_OK) == 0) 39 | { 40 | gchar* qroot = g_shell_quote(root); 41 | gchar* cmd = g_strdup_printf("/sbin/ldconfig -r %s", qroot); 42 | g_free(qroot); 43 | 44 | _notice("Running /sbin/ldconfig..."); 45 | if (!opts->dryrun) 46 | { 47 | gint rv = system(cmd); 48 | if (rv < 0) 49 | _warning("Can't execute /sbin/ldconfig. (%s)", strerror(errno)); 50 | else if (rv > 0) 51 | _warning("Program /sbin/ldconfig failed. (%d)", rv); 52 | } 53 | 54 | g_free(cmd); 55 | } 56 | g_free(ldconf_file); 57 | } 58 | else 59 | { 60 | _warning("Program /sbin/ldconfig was not found on the system."); 61 | } 62 | } 63 | 64 | void _gtk_update_icon_cache(const gchar* root, const struct cmd_options* opts) 65 | { 66 | if (access("/usr/bin/gtk-update-icon-cache", X_OK) == 0) 67 | { 68 | gchar* cmd = g_strdup_printf("/usr/bin/gtk-update-icon-cache %susr/share/icons/hicolor > /dev/null 2>&1", root); 69 | 70 | _notice("Running /usr/bin/gtk-update-icon-cache..."); 71 | if (!opts->dryrun) 72 | { 73 | gint rv = system(cmd); 74 | if (rv < 0) 75 | _warning("Can't execute /usr/bin/gtk-update-icon-cache. (%s)", strerror(errno)); 76 | else if (rv > 0) 77 | _warning("Program /usr/bin/gtk-update-icon-cache failed. (%d)", rv); 78 | } 79 | } 80 | else 81 | { 82 | _warning("Program /usr/bin/gtk-update-icon-cache was not found on the system."); 83 | } 84 | } 85 | 86 | gboolean _unsafe_path(const gchar* path) 87 | { 88 | if (g_path_is_absolute(path)) 89 | return TRUE; 90 | else if (!strncmp(path, "../", 3)) 91 | return TRUE; 92 | return FALSE; 93 | } 94 | 95 | void _read_slackdesc(struct untgz_state* tgz, struct db_pkg* pkg) 96 | { 97 | gchar *buf = NULL, *desc[MAX_SLACKDESC_LINES] = {0}; 98 | gsize len; 99 | untgz_write_data(tgz, &buf, &len); 100 | parse_slackdesc(buf, pkg->shortname, desc); 101 | pkg->desc = gen_slackdesc(pkg->shortname, desc); 102 | g_free(buf); 103 | 104 | /* free description */ 105 | gint i; 106 | for (i=0;ino_optsyms || is_blacklisted(pkg->shortname, opts->bl_symopts)) 123 | { 124 | _debug("Symlink optimization is disabled."); 125 | if (opts->safe) 126 | { 127 | _warning("In safe mode, install script is not executed," 128 | " and with disabled optimized symlink creation, symlinks" 129 | " will not be created.%s", is_blacklisted(pkg->shortname, opts->bl_symopts) ? 130 | " Note that this package is blacklisted for optimized" 131 | " symlink creation. This may change in the future as" 132 | " better heuristics are developed for extracting symlink" 133 | " creation code from install script." : ""); 134 | } 135 | else 136 | { 137 | if (!opts->dryrun) 138 | { 139 | if (untgz_write_file(tgz, fullpath)) 140 | { 141 | e_set(E_ERROR, "Failed to extract file %s.", sane_path); 142 | goto err0; 143 | } 144 | } 145 | has_doinst = 1; 146 | } 147 | goto done; 148 | } 149 | 150 | /* EXIT: free(fullpath) */ 151 | 152 | /* read doinst.sh into buffer */ 153 | gchar* buf; 154 | gsize len; 155 | if (untgz_write_data(tgz, &buf, &len)) 156 | { 157 | e_set(E_ERROR, "Failed to read post-installation script into buffer."); 158 | goto err0; 159 | } 160 | 161 | /* EXIT: free(fullpath), free(buf) */ 162 | 163 | _debug("Extracting symlinks from the post-installation script..."); 164 | 165 | /* optimize out symlinks creation from doinst.sh */ 166 | GSList *doinst = NULL; 167 | gsize doinst_len = 0; 168 | gchar *b, *end, *ln = NULL, *n = buf, *sane_link_path = NULL, 169 | *link_target = NULL, *link_fullpath = NULL; 170 | while(iter_str_lines(&b, &end, &n, &ln)) 171 | { /* for each line */ 172 | gchar *link_dir, *link_name; 173 | 174 | /* EXIT: free(fullpath), free(buf), free(ln) */ 175 | 176 | /* create link line */ 177 | if (parse_createlink(ln, &link_dir, &link_name, &link_target)) 178 | { 179 | struct stat ex_stat; 180 | gchar* link_path = g_strdup_printf("%s/%s", link_dir, link_name); 181 | sane_link_path = path_simplify(link_path); 182 | link_fullpath = g_strdup_printf("%s%s", root, sane_link_path); 183 | g_free(link_dir); 184 | g_free(link_name); 185 | g_free(link_path); 186 | 187 | /* EXIT: free(fullpath), free(buf), free(ln), free(link_target), 188 | free(sane_link_path), free(link_fullpath) */ 189 | 190 | /* link path checks (be careful here) */ 191 | if (_unsafe_path(sane_link_path)) 192 | { 193 | e_set(E_ERROR, "Package contains symlink with unsafe path. (%s)", sane_link_path); 194 | goto parse_failed; 195 | } 196 | 197 | /* treat an install just as an upgrade where the file didn't exist */ 198 | db_path_type orig_ptype = DB_PATH_NONE; 199 | if (do_upgrade) 200 | { 201 | orig_ptype = db_pkg_get_path(ipkg, sane_link_path); 202 | } 203 | 204 | _debug("Symlink detected: %s -> %s", sane_link_path, link_target); 205 | if (db_pkg_add_path(pkg, sane_link_path, DB_PATH_SYMLINK)) 206 | { 207 | e_set(E_ERROR, "Can't add path to the package, it's too long. (%s)", sane_link_path); 208 | goto parse_failed; 209 | } 210 | sys_ftype ex_type = sys_file_type_stat(link_fullpath, 0, &ex_stat); 211 | 212 | if (ex_type == SYS_ERR) 213 | { 214 | e_set(E_ERROR, "Can't check path for symlink. (%s)", sane_link_path); 215 | goto parse_failed; 216 | } 217 | else if (ex_type == SYS_NONE) 218 | { 219 | ta_symlink_nothing(link_fullpath, g_strdup(link_target)); /* target is freed by db_free_pkg(), dup by taction finalize/rollback */ 220 | link_fullpath = NULL; 221 | } 222 | else 223 | { 224 | /* If this path was not in the original package if upgrading. 225 | This is always going to be the case if installing. */ 226 | if (orig_ptype == DB_PATH_NONE) 227 | { 228 | if (opts->safe) 229 | { 230 | e_set(E_ERROR, "Can't create symlink over existing %s. (%s)", ex_type == SYS_DIR ? "directory" : "file", sane_link_path); 231 | goto parse_failed; 232 | } 233 | _warning("%s exists, where symlink should be created. It will be removed. (%s)", ex_type == SYS_DIR ? "Directory" : "File", sane_link_path); 234 | } 235 | ta_forcesymlink_nothing(link_fullpath, g_strdup(link_target)); 236 | link_fullpath = NULL; 237 | } 238 | 239 | g_free(link_fullpath); 240 | g_free(sane_link_path); 241 | } 242 | /* if this is not 'delete old file' line... */ 243 | else if (!parse_cleanuplink(ln)) 244 | { 245 | /* ...append it to doinst buffer */ 246 | doinst = g_slist_prepend(doinst, ln); 247 | doinst_len += end - b + 1; /* line len + eol */ 248 | ln = NULL; /* will be freed later */ 249 | } 250 | 251 | g_free(ln); 252 | } /* iter_lines */ 253 | 254 | /* EXIT: free(fullpath), free(buf), free(doinst) */ 255 | 256 | /* we always store full doinst.sh in database (buf freed by db_free_pkg()) */ 257 | pkg->doinst = buf; 258 | 259 | /* EXIT: free(fullpath), free(doinst) */ 260 | 261 | /* write stripped down version of doinst.sh to a file */ 262 | if (doinst != NULL) 263 | { 264 | _debug("Saving optimized post-installation script..."); 265 | 266 | if (!opts->dryrun) 267 | { 268 | gchar* doinst_buf = g_malloc(doinst_len*2); 269 | gchar* doinst_buf_ptr = doinst_buf; 270 | doinst = g_slist_reverse(doinst); 271 | GSList* i; 272 | for (i = doinst; i != 0; i = i->next) 273 | { 274 | strcpy(doinst_buf_ptr, i->data); 275 | doinst_buf_ptr += strlen(i->data); 276 | *doinst_buf_ptr = '\n'; 277 | doinst_buf_ptr++; 278 | } 279 | if (sys_write_buffer_to_file(fullpath, doinst_buf, doinst_len, e)) 280 | { 281 | e_set(E_ERROR, "Can't write buffer to file %s.", sane_path); 282 | g_free(doinst_buf); 283 | g_slist_foreach(doinst, (GFunc)g_free, 0); 284 | g_slist_free(doinst); 285 | goto err0; 286 | } 287 | g_free(doinst_buf); 288 | } 289 | g_slist_foreach(doinst, (GFunc)g_free, 0); 290 | g_slist_free(doinst); 291 | has_doinst = 1; 292 | } 293 | 294 | done: 295 | err0: 296 | g_free(fullpath); 297 | return has_doinst; 298 | parse_failed: 299 | g_free(link_target); 300 | g_free(link_fullpath); 301 | g_free(sane_link_path); 302 | g_free(ln); 303 | goto err0; 304 | } 305 | 306 | void _extract_file(struct untgz_state* tgz, struct db_pkg* pkg, 307 | const gchar* sane_path, const gchar* root, 308 | const struct cmd_options* opts, struct error* e, 309 | gboolean do_upgrade, struct db_pkg* ipkg) 310 | { 311 | gchar context[] = "install"; 312 | if (do_upgrade) 313 | strcpy(context, "upgrade"); 314 | /* following strings can be freed by the ta_* code, if so, you must zero 315 | variables after passing them to a ta_* function */ 316 | gchar* fullpath = g_strdup_printf("%s%s", root, sane_path); 317 | gchar* temppath = g_strdup_printf("%s--###%s###", fullpath, context); 318 | 319 | /* EXIT: free(fullpath), free(temppath) */ 320 | 321 | /* Here we must check interaction of following conditions: 322 | * 323 | * - type of the file we are installing (tgz->f_type) 324 | * - type of the file on the filesystem (existing) 325 | * - presence of the file in the file database (install) 326 | * or original package (upgrade) 327 | * 328 | * And decide what to do: 329 | * 330 | * - install new file 331 | * - overwrite existing file 332 | * - leave existing file alone 333 | * - issue error and rollback installation 334 | * - issue notice or warning 335 | */ 336 | 337 | /* EXIT: free(fullpath), free(temppath) */ 338 | 339 | /* treat an install just as an upgrade where the file didn't exist */ 340 | db_path_type orig_ptype = DB_PATH_NONE; 341 | if (do_upgrade) 342 | orig_ptype = db_pkg_get_path(ipkg, sane_path); 343 | 344 | /* get information about installed file from filesystem and filedb */ 345 | struct stat ex_stat; 346 | sys_ftype ex_type = sys_file_type_stat(fullpath, 0, &ex_stat); 347 | sys_ftype ex_deref_type = SYS_NONE; 348 | if (ex_type == SYS_SYM) 349 | ex_deref_type = sys_file_type(fullpath, 1); 350 | 351 | if (ex_type == SYS_ERR) 352 | { 353 | e_set(E_ERROR, "Can't check path. (%s)", sane_path); 354 | goto extract_failed; 355 | } 356 | 357 | // installed file type 358 | switch (tgz->f_type) 359 | { 360 | case UNTGZ_DIR: /* we have directory */ 361 | { 362 | if (ex_type == SYS_DIR) 363 | { 364 | /* installed directory already exist */ 365 | if (_mode_differ(tgz, &ex_stat) || _gid_or_uid_differ(tgz, &ex_stat)) 366 | { 367 | _notice("Directory already exists %s (but permissions differ)", sane_path); 368 | if (!opts->safe) 369 | { 370 | _notice("Permissions will be changed to owner=%d, group=%d, mode=%03o.", tgz->f_uid, tgz->f_gid, tgz->f_mode); 371 | ta_chperm_nothing(fullpath, tgz->f_mode, tgz->f_uid, tgz->f_gid); 372 | fullpath = NULL; 373 | } 374 | else 375 | { 376 | e_set(E_ERROR, "Can't change existing directory permissions in safe mode. (%s)", sane_path); 377 | goto extract_failed; 378 | } 379 | } 380 | else 381 | { 382 | _debug("Directory already exists %s", sane_path); 383 | } 384 | } 385 | else if (ex_type == SYS_SYM && ex_deref_type == SYS_DIR) 386 | { 387 | _warning("Directory already exists *behind the symlink* on filesystem. This may break upgrade/remove if you change that symlink in the future. (%s)", sane_path); 388 | } 389 | else if (ex_type == SYS_NONE) 390 | { 391 | _notice("Creating directory %s", sane_path); 392 | 393 | if (!opts->dryrun) 394 | { 395 | if (untgz_write_file(tgz, fullpath)) 396 | goto extract_failed; 397 | } 398 | 399 | ta_keep_remove(fullpath, 1); 400 | fullpath = NULL; 401 | } 402 | else /* create directory over file */ 403 | { 404 | if (opts->safe) 405 | { 406 | e_set(E_ERROR, "Can't create directory over ordinary file. (%s)", sane_path); 407 | goto extract_failed; 408 | } 409 | _notice("Creating directory over ordinary file (%s)", sane_path); 410 | if (!opts->dryrun) 411 | { 412 | if (unlink(fullpath) < 0) 413 | { 414 | e_set(E_ERROR, "Couldn't remove file during upgrade. (%s)", sane_path); 415 | goto extract_failed; 416 | } 417 | if (untgz_write_file(tgz, fullpath)) 418 | goto extract_failed; 419 | } 420 | 421 | ta_keep_remove(fullpath, 1); 422 | fullpath = NULL; 423 | } 424 | } 425 | break; 426 | case UNTGZ_SYM: /* we have a symlink */ 427 | { 428 | #ifdef LEGACY_CHECKS 429 | e_set(E_ERROR, "Symlink was found in the archive. (%s)", sane_path); 430 | goto extract_failed; 431 | #else 432 | _debug("Symlink detected: %s -> %s", sane_path, tgz->f_link); 433 | if (ex_type == SYS_NONE) 434 | { 435 | ta_symlink_nothing(fullpath, g_strdup(tgz->f_link)); /* target is freed by db_free_pkg(), dup by taction finalize/rollback */ 436 | fullpath = NULL; 437 | } 438 | else 439 | { 440 | if (opts->safe) 441 | { 442 | e_set(E_ERROR, "Can't create symlink over existing %s. (%s)", ex_type == SYS_DIR ? "directory" : "file", sane_path); 443 | goto extract_failed; 444 | } 445 | else 446 | { 447 | _warning("%s exists, where symlink should be created. It will be removed. (%s)", ex_type == SYS_DIR ? "Directory" : "File", sane_path); 448 | ta_forcesymlink_nothing(fullpath, g_strdup(tgz->f_link)); 449 | fullpath = NULL; 450 | } 451 | } 452 | #endif 453 | } 454 | break; 455 | case UNTGZ_LNK: /* we have a hardlink */ 456 | { 457 | /* hardlinks are special beasts, most easy solution is to 458 | * postpone hardlink creation into transaction finalization phase 459 | */ 460 | gchar* linkpath = g_strdup_printf("%s%s", root, tgz->f_link); 461 | 462 | /* check file we will be linking to (it should be a regular file) */ 463 | sys_ftype tgt_type = sys_file_type(linkpath, 0); 464 | if (tgt_type == SYS_ERR) 465 | { 466 | e_set(E_ERROR, "Can't check hardlink target path. (%s)", linkpath); 467 | g_free(linkpath); 468 | goto extract_failed; 469 | } 470 | else if (tgt_type == SYS_REG) 471 | { 472 | _debug("Hardlink detected: %s -> %s", sane_path, tgz->f_link); 473 | 474 | /* when creating hardlink, nothing must exist on created path */ 475 | if (ex_type == SYS_NONE) 476 | { 477 | ta_link_nothing(fullpath, linkpath); /* link path freed by ta_* */ 478 | fullpath = NULL; 479 | } 480 | else 481 | { 482 | /* If this path was not in the original package if upgrading. 483 | This is always going to be the case if installing. */ 484 | if (orig_ptype == DB_PATH_NONE) 485 | { 486 | if (opts->safe) 487 | { 488 | e_set(E_ERROR, "Can't create hardlink over existing %s. (%s)", ex_type == SYS_DIR ? "directory" : "file", sane_path); 489 | g_free(linkpath); 490 | goto extract_failed; 491 | } 492 | _warning("%s exists, where hardlink should be created. It will be removed. (%s)", ex_type == SYS_DIR ? "Directory" : "File", sane_path); 493 | } 494 | ta_forcelink_nothing(fullpath, linkpath); 495 | fullpath = NULL; 496 | } 497 | } 498 | else 499 | { 500 | if (!opts->dryrun) 501 | { 502 | e_set(E_ERROR, "Hardlink target is NOT a regular file. (%s)", linkpath); 503 | g_free(linkpath); 504 | goto extract_failed; 505 | } 506 | g_free(linkpath); 507 | } 508 | } 509 | break; 510 | case UNTGZ_NONE: /* nothing? tar is broken */ 511 | { 512 | e_set(E_ERROR, "Broken tar archive."); 513 | goto extract_failed; 514 | } 515 | break; 516 | default: /* ordinary file */ 517 | { 518 | _notice("Installing file %s", sane_path); 519 | 520 | if (ex_type == SYS_DIR) 521 | { 522 | /* target path is a directory, bad! */ 523 | if (opts->safe) { 524 | e_set(E_ERROR, "Can't create file over existing directory. (%s)", sane_path); 525 | goto extract_failed; 526 | } 527 | 528 | _notice("Creating ordinary file over directory (%s)", sane_path); 529 | if (!opts->dryrun) 530 | { 531 | if (sys_rm_rf(fullpath) < 0) 532 | { 533 | e_set(E_ERROR, "Couldn't remove directory during upgrade. (%s)", sane_path); 534 | goto extract_failed; 535 | } 536 | if (untgz_write_file(tgz, fullpath)) 537 | goto extract_failed; 538 | } 539 | 540 | ta_keep_remove(fullpath, 1); 541 | fullpath = NULL; 542 | } 543 | else if (ex_type == SYS_NONE) 544 | { 545 | if (!opts->dryrun) 546 | { 547 | if (untgz_write_file(tgz, fullpath)) 548 | goto extract_failed; 549 | } 550 | 551 | ta_keep_remove(fullpath, 0); 552 | fullpath = NULL; 553 | } 554 | else /* file already exist there */ 555 | { 556 | if (do_upgrade) 557 | _notice("Upgrading file %s", sane_path); 558 | /* If this path was not in the original package if upgrading. 559 | This is always going to be the case if installing. */ 560 | if (orig_ptype == DB_PATH_NONE) 561 | { 562 | if (opts->safe) 563 | { 564 | if (do_upgrade) 565 | e_set(E_ERROR, "File already exist, but it was not installed by the upgraded package. (%s)", sane_path); 566 | else 567 | e_set(E_ERROR, "File already exist. (%s)", sane_path); 568 | goto extract_failed; 569 | } 570 | if (do_upgrade) 571 | _warning("File already exist, but it was not installed by the upgraded package. (%s)", sane_path); 572 | } 573 | if (!do_upgrade) 574 | _warning("File already exist %s (it will be replaced)", sane_path); 575 | sys_ftype tmp_type = sys_file_type(temppath, 0); 576 | if (tmp_type == SYS_ERR) 577 | { 578 | e_set(E_ERROR, "Can't check temporary file path. (%s)", temppath); 579 | goto extract_failed; 580 | } 581 | else if (tmp_type == SYS_DIR) 582 | { 583 | e_set(E_ERROR, "Temporary file path is used by a directory. (%s)", temppath); 584 | goto extract_failed; 585 | } 586 | else if (tmp_type != SYS_NONE) 587 | { 588 | _warning("Temporary file already exists, removing %s", temppath); 589 | if (!opts->dryrun) 590 | { 591 | if (unlink(temppath) < 0) 592 | { 593 | e_set(E_ERROR, "Can't remove temporary file %s. (%s)", temppath, strerror(errno)); 594 | goto extract_failed; 595 | } 596 | } 597 | } 598 | 599 | if (!opts->dryrun) 600 | { 601 | if (untgz_write_file(tgz, temppath)) 602 | goto extract_failed; 603 | } 604 | 605 | ta_move_remove(temppath, fullpath); 606 | fullpath = temppath = NULL; 607 | } 608 | } 609 | break; 610 | } 611 | 612 | done: 613 | g_free(temppath); 614 | g_free(fullpath); 615 | return; 616 | extract_failed: 617 | e_set(E_ERROR, "Failed to extract file %s.", sane_path); 618 | goto done; 619 | } 620 | 621 | /* This just copies a file from src to dest */ 622 | gboolean _copy_file(const gchar *src, const gchar *dest) { 623 | FILE *source, *destination; 624 | gchar buffer[4096]; 625 | gsize bytes; 626 | 627 | /* Open source file */ 628 | source = fopen(src, "rb"); 629 | if (source == NULL) { 630 | _warning("Error reading douninst.sh script: %s\n", src); 631 | return FALSE; 632 | } 633 | 634 | /* Open destination file */ 635 | destination = fopen(dest, "wb"); 636 | if (destination == NULL) { 637 | _warning("Error opening douninst.sh script for writing: %s\n", dest); 638 | fclose(source); 639 | return FALSE; 640 | } 641 | 642 | /* Copy data in chunks */ 643 | while ((bytes = fread(buffer, 1, sizeof(buffer), source)) > 0) { 644 | if (fwrite(buffer, 1, bytes, destination) != bytes) { 645 | _warning("Error writing to destination file: %s\n", dest); 646 | fclose(source); 647 | fclose(destination); 648 | return FALSE; 649 | } 650 | } 651 | 652 | /* Check for read errors */ 653 | if (ferror(source)) { 654 | _warning("Error reading source file: %s\n", src); 655 | fclose(source); 656 | fclose(destination); 657 | return FALSE; 658 | } 659 | 660 | fclose(source); 661 | fclose(destination); 662 | return TRUE; 663 | } 664 | 665 | 666 | /* Copy the douninst.sh script to /var/tmp/spkg/ */ 667 | void _copy_douninst_sh(const gchar* pkgname, const struct cmd_options* opts, const gchar* root) 668 | { 669 | gchar src_path[MAXPATHLEN]; 670 | gchar dest_path[MAXPATHLEN]; 671 | 672 | snprintf(src_path, sizeof(src_path), "%s/var/lib/pkgtools/douninst.sh/%s", root, pkgname); 673 | snprintf(dest_path, sizeof(dest_path), "%s/var/tmp/spkg/%s", root, pkgname); 674 | 675 | struct stat st; 676 | if (stat(src_path, &st) == 0 && S_ISREG(st.st_mode)) 677 | { 678 | if (!opts->no_scripts) 679 | { 680 | /* Create the destination directory if it doesn't exist */ 681 | gchar* dir_path = g_path_get_dirname(dest_path); 682 | if (g_mkdir_with_parents(dir_path, 0755) != 0) { 683 | _warning("Failed to create directory for moving douninst.sh script: %s", dir_path); 684 | g_free(dir_path); 685 | return; 686 | } 687 | g_free(dir_path); 688 | 689 | /* Copy the script */ 690 | if (!_copy_file(src_path, dest_path)) { 691 | _warning("Failed to copy douninst.sh script from %s to %s", src_path, dest_path); 692 | } 693 | } 694 | else 695 | { 696 | _notice("Skipping moving douninst.sh script as --no-scripts is specified"); 697 | } 698 | } 699 | else 700 | { 701 | _notice("douninst.sh script not found for package %s", pkgname); 702 | } 703 | } 704 | 705 | /* Run the douninst.sh script for the package */ 706 | void _run_douninst_sh(const gchar* pkgname, const struct cmd_options* opts, const gchar* root) 707 | { 708 | gchar script_path[MAXPATHLEN]; 709 | gchar script_path_with_root[MAXPATHLEN]; 710 | snprintf(script_path, sizeof(script_path), "var/tmp/spkg/%s", pkgname); 711 | snprintf(script_path_with_root, sizeof(script_path_with_root), "%svar/tmp/spkg/%s", root, pkgname); 712 | 713 | struct stat st; 714 | if (stat(script_path_with_root, &st) == 0 && S_ISREG(st.st_mode)) 715 | { 716 | if (!opts->no_scripts) 717 | { 718 | gchar* cmd = g_strdup_printf("cd %s && sh %s", root, script_path); 719 | int result = system(cmd); 720 | /* douninst.sh script was executed succesfully, so move it to removed_uninstall_scripts */ 721 | if (result == 0) 722 | { 723 | gchar dest_path[MAXPATHLEN]; 724 | snprintf(dest_path, sizeof(dest_path), "%svar/log/pkgtools/removed_uninstall_scripts", root); 725 | /* Check if the destination directory exists, and create it if it doesn't */ 726 | if (stat(dest_path, &st) != 0 || !S_ISDIR(st.st_mode)) 727 | { 728 | if (mkdir(dest_path, 0755) != 0 && errno != EEXIST) 729 | { 730 | _warning("Could not create directory %s", dest_path); 731 | g_free(cmd); 732 | return; 733 | } 734 | } 735 | snprintf(dest_path, sizeof(dest_path), "%svar/log/pkgtools/removed_uninstall_scripts/%s", root, pkgname); 736 | if (rename(script_path_with_root, dest_path) != 0) 737 | { 738 | _warning("Could not move %s script to %s.", script_path_with_root, dest_path); 739 | } 740 | } 741 | else 742 | { 743 | _warning("douninst.sh script execution failed with status %d", result); 744 | } 745 | g_free(cmd); 746 | } 747 | else 748 | { 749 | _notice("Skipping douninst.sh script execution as --no-scripts is specified"); 750 | } 751 | } 752 | else 753 | { 754 | _notice("douninst.sh script not found for package %s", pkgname); 755 | } 756 | } --------------------------------------------------------------------------------