├── .gitignore ├── AUTHORS ├── COPYING ├── HISTORY ├── LICENSE ├── Makefile.am ├── README.md ├── TRANSLATE ├── autogen.sh ├── configure.ac ├── doc └── kalu.pod ├── m4 ├── cflagsadd.m4 ├── pathmax.m4 └── po.m4 ├── misc ├── 30-kalu.rules.tpl ├── arch_linux_48x48_icon_by_painlessrob.png ├── arch_linux_48x48_icon_by_painlessrob_resized_16x16.png ├── kalu.desktop ├── org.jjk.kalu.conf ├── org.jjk.kalu.policy └── org.jjk.kalu.service.tpl ├── po ├── .gitignore ├── LINGUAS ├── Makefile.in.in ├── Makevars ├── POTFILES.in ├── es.po ├── fr.po ├── nb.po └── remove-potcdate.sin └── src ├── helper └── serialize.c ├── kalu-dbus ├── gen-interface ├── kalu-dbus-launcher ├── kalu-dbus.c ├── kupdater.h └── updater-dbus.xml └── kalu ├── aur.c ├── aur.h ├── cJSON.README ├── cJSON.c ├── cJSON.h ├── closures ├── closures.c ├── closures.def ├── closures.h ├── conf.c ├── conf.h ├── curl.c ├── curl.h ├── gui.c ├── gui.h ├── imagemenuitem.c ├── imagemenuitem.h ├── kalu-alpm.c ├── kalu-alpm.h ├── kalu-updater.c ├── kalu-updater.h ├── kalu.h ├── main.c ├── news.c ├── news.h ├── preferences.c ├── preferences.h ├── rt_timeout.c ├── rt_timeout.h ├── shared.c ├── shared.h ├── updater.c ├── updater.h ├── util-gtk.c ├── util-gtk.h ├── util.c ├── util.h ├── watched.c └── watched.h /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.lo 3 | *.la 4 | .deps/ 5 | .libs/ 6 | build-aux/ 7 | Makefile 8 | Makefile.in 9 | aclocal.m4 10 | autogen.log 11 | autom4te.cache/ 12 | compile 13 | config.h 14 | config.h.in 15 | config.log 16 | config.status 17 | configure 18 | /kalu 19 | /kalu-dbus 20 | /serialize 21 | kalu.png 22 | kalu-logo 23 | libtool 24 | doc/kalu.1 25 | doc/index.html 26 | src/kalu-dbus/updater-dbus.h 27 | src/logo.c 28 | m4/libtool.m4 29 | m4/ltoptions.m4 30 | m4/ltsugar.m4 31 | m4/ltversion.m4 32 | m4/lt~obsolete.m4 33 | misc/org.jjk.kalu.service 34 | misc/30-kalu.rules 35 | stamp-h1 36 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | kalu is developed by Olivier Brunel, using cJSON[1] by Dave Gamble 2 | See LICENSE for more 3 | 4 | kalu's icon was made by Painless Rob[2] 5 | 6 | [1]: http://sourceforge.net/projects/cjson/ 7 | [2]: https://bbs.archlinux.org/viewtopic.php?id=130839 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | kalu is released under the GNU General Public License v3+ 2 | Copyright (C) 2012-2018 Olivier Brunel 3 | See COPYING 4 | 5 | ------------------------------------------ 6 | 7 | {conf,util}.c are: 8 | Copyright (C) 2012-2018 Olivier Brunel 9 | Copyright (c) 2006-2011 Pacman Development Team 10 | 11 | ------------------------------------------ 12 | 13 | cJSON.{h,c} are Copyright (c) 2009 Dave Gamble 14 | 15 | Permission is hereby granted, free of charge, to any person obtaining a copy 16 | of this software and associated documentation files (the "Software"), to deal 17 | in the Software without restriction, including without limitation the rights 18 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 19 | copies of the Software, and to permit persons to whom the Software is 20 | furnished to do so, subject to the following conditions: 21 | 22 | The above copyright notice and this permission notice shall be included in 23 | all copies or substantial portions of the Software. 24 | 25 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 31 | THE SOFTWARE. 32 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | DISTCLEANFILES = \ 2 | src/kalu-dbus/updater-dbus.h \ 3 | src/logo.c \ 4 | doc/kalu.1 \ 5 | doc/index.html 6 | 7 | CLEANFILES = \ 8 | kalu.png \ 9 | kalu-logo \ 10 | misc/org.jjk.kalu.service \ 11 | misc/30-kalu.rules 12 | 13 | ACLOCAL_AMFLAGS = -I m4 14 | 15 | SUBDIRS = po 16 | 17 | DEFS = \ 18 | -DLOCALEDIR=\"@localedir@\" \ 19 | @DEFS@ 20 | 21 | if USE_GIT_VERSION 22 | _VERSION = `git describe --abbrev=4 --dirty` 23 | DEFS += -DGIT_VERSION=\"$(_VERSION)\" 24 | else 25 | _VERSION = $(PACKAGE_VERSION) 26 | endif 27 | 28 | bin_PROGRAMS = kalu 29 | if ! DISABLE_UPDATER 30 | bin_PROGRAMS += kalu-dbus 31 | dist_bin_SCRIPTS = src/kalu-dbus/kalu-dbus-launcher 32 | endif 33 | 34 | noinst_PROGRAMS = serialize 35 | serialize_SOURCES = \ 36 | src/helper/serialize.c 37 | 38 | AM_CFLAGS = \ 39 | -g \ 40 | -DDOCDIR='"$(docdir)"' \ 41 | ${WARNING_CFLAGS} 42 | 43 | noinst_LTLIBRARIES = libshared.la 44 | libshared_la_SOURCES = \ 45 | src/kalu/shared.h \ 46 | src/kalu/shared.c 47 | 48 | kalu_CFLAGS = ${AM_CFLAGS} 49 | kalu_LDADD = libshared.la -lalpm -lm @LIBCURL_LIBS@ 50 | kalu_SOURCES = \ 51 | src/kalu/main.c \ 52 | src/kalu/kalu.h \ 53 | src/kalu/conf.h \ 54 | src/kalu/conf.c \ 55 | src/kalu/util.h \ 56 | src/kalu/util.c \ 57 | src/kalu/kalu-alpm.h \ 58 | src/kalu/kalu-alpm.c \ 59 | src/kalu/curl.h \ 60 | src/kalu/curl.c \ 61 | src/kalu/cJSON.h \ 62 | src/kalu/cJSON.c \ 63 | src/kalu/aur.h \ 64 | src/kalu/aur.c \ 65 | src/kalu/news.h \ 66 | src/kalu/news.c \ 67 | src/kalu/rt_timeout.h \ 68 | src/kalu/rt_timeout.c 69 | 70 | if ! DISABLE_GUI 71 | kalu_CFLAGS += @GTK_CFLAGS@ @NOTIFY_CFLAGS@ 72 | kalu_LDADD += \ 73 | @GTK_LIBS@ \ 74 | @NOTIFY_LIBS@ 75 | kalu_SOURCES += \ 76 | src/kalu/imagemenuitem.h \ 77 | src/kalu/imagemenuitem.c \ 78 | src/kalu/gui.h \ 79 | src/kalu/gui.c \ 80 | src/kalu/util-gtk.h \ 81 | src/kalu/util-gtk.c \ 82 | src/kalu/watched.h \ 83 | src/kalu/watched.c \ 84 | src/kalu/preferences.h \ 85 | src/kalu/preferences.c \ 86 | src/logo.c 87 | else 88 | kalu_CFLAGS += @GLIB2_CFLAGS@ 89 | kalu_LDADD += @GLIB2_LIBS@ 90 | endif 91 | 92 | if ENABLE_STATUS_NOTIFIER 93 | kalu_CFLAGS += @STATUS_NOTIFIER_CFLAGS@ 94 | kalu_LDADD += @STATUS_NOTIFIER_LIBS@ 95 | endif 96 | 97 | BUILT_SOURCES = \ 98 | src/logo.c 99 | 100 | if ! DISABLE_UPDATER 101 | BUILT_SOURCES += \ 102 | src/kalu-dbus/updater-dbus.h 103 | 104 | kalu_SOURCES += \ 105 | src/kalu-dbus/updater-dbus.h \ 106 | src/kalu-dbus/kupdater.h \ 107 | src/kalu/closures.h \ 108 | src/kalu/closures.c \ 109 | src/kalu/kalu-updater.h \ 110 | src/kalu/kalu-updater.c \ 111 | src/kalu/updater.h \ 112 | src/kalu/updater.c 113 | 114 | kalu_dbus_CFLAGS = ${AM_CFLAGS} @GTK_CFLAGS@ @POLKIT_CFLAGS@ 115 | kalu_dbus_LDADD = libshared.la -lalpm @GTK_LIBS@ @POLKIT_LIBS@ 116 | kalu_dbus_SOURCES = \ 117 | src/kalu-dbus/updater-dbus.h \ 118 | src/kalu-dbus/kupdater.h \ 119 | src/kalu-dbus/kalu-dbus.c 120 | endif 121 | 122 | if ! DISABLE_GUI 123 | logodir = $(datadir)/pixmaps 124 | logo_DATA = kalu.png 125 | 126 | hicolordir = $(datadir)/icons/hicolor/48x48/apps 127 | hicolor_DATA = kalu.png 128 | 129 | hicolor16dir = $(datadir)/icons/hicolor/16x16/apps 130 | hicolor16_DATA = kalu16.png 131 | 132 | desktopdir = /usr/share/applications 133 | dist_desktop_DATA = misc/kalu.desktop 134 | endif 135 | 136 | if ! DISABLE_UPDATER 137 | policydir = /usr/share/polkit-1/actions 138 | dist_policy_DATA = misc/org.jjk.kalu.policy 139 | rulesdir = /usr/share/polkit-1/rules.d 140 | dist_rules_DATA = misc/30-kalu.rules 141 | dbusservicedir = /usr/share/dbus-1/system-services 142 | nodist_dbusservice_DATA = misc/org.jjk.kalu.service 143 | dbusconfdir = /etc/dbus-1/system.d 144 | dist_dbusconf_DATA = misc/org.jjk.kalu.conf 145 | endif 146 | 147 | dist_man_MANS = doc/kalu.1 148 | dist_doc_DATA = doc/index.html \ 149 | HISTORY \ 150 | AUTHORS \ 151 | COPYING \ 152 | LICENSE \ 153 | README.md 154 | 155 | EXTRA_DIST = \ 156 | src/kalu-dbus/gen-interface \ 157 | src/kalu-dbus/updater-dbus.xml \ 158 | doc/kalu.pod \ 159 | misc/org.jjk.kalu.service.tpl \ 160 | misc/30-kalu.rules.tpl \ 161 | misc/arch_linux_48x48_icon_by_painlessrob.png \ 162 | misc/arch_linux_48x48_icon_by_painlessrob_resized_16x16.png 163 | 164 | src/kalu-dbus/updater-dbus.h: src/kalu-dbus/updater-dbus.xml 165 | $(AM_V_GEN)cd src/kalu-dbus && ./gen-interface > updater-dbus.h 166 | 167 | src/logo.c: kalu-logo serialize 168 | $(AM_V_GEN)./serialize kalu_logo kalu-logo > src/logo.c 169 | 170 | kalu-logo: kalu.png 171 | $(AM_V_at)$(LN_S) kalu.png kalu-logo 172 | 173 | doc/kalu.1: doc/kalu.pod 174 | $(AM_V_GEN)pod2man --center='Keeping Arch Linux Up-to-date' --section=1 \ 175 | --release=$(_VERSION) doc/kalu.pod doc/kalu.1 176 | 177 | doc/index.html: doc/kalu.1 178 | $(AM_V_GEN)groff -T html -man doc/kalu.1 > doc/index.html 179 | 180 | misc/org.jjk.kalu.service: misc/org.jjk.kalu.service.tpl 181 | $(AM_V_GEN)cd misc && sed 's|@BINDIR@|$(bindir)|' org.jjk.kalu.service.tpl \ 182 | > org.jjk.kalu.service 183 | 184 | misc/30-kalu.rules: misc/30-kalu.rules.tpl 185 | $(AM_V_GEN)cd misc && sed 's|@GROUP@|$(SYSUPGRADE_GROUP)|' 30-kalu.rules.tpl \ 186 | > 30-kalu.rules 187 | 188 | kalu.png: misc/arch_linux_48x48_icon_by_painlessrob.png 189 | $(AM_V_GEN)$(LN_S) misc/arch_linux_48x48_icon_by_painlessrob.png kalu.png 190 | 191 | kalu16.png: misc/arch_linux_48x48_icon_by_painlessrob_resized_16x16.png 192 | $(AM_V_GEN)$(LN_S) misc/arch_linux_48x48_icon_by_painlessrob_resized_16x16.png kalu16.png 193 | 194 | install-data-hook: 195 | mkdir "$(DESTDIR)$(docdir)/html" 196 | mv "$(DESTDIR)$(docdir)/index.html" "$(DESTDIR)$(docdir)/html/" 197 | if ! DISABLE_GUI 198 | mv "$(DESTDIR)$(hicolor16dir)/kalu16.png" "$(DESTDIR)$(hicolor16dir)/kalu.png" 199 | endif 200 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # kalu: Keeping Arch Linux Up-to-date 2 | 3 | kalu (which could stand for "Keeping Arch Linux Up-to-date") is a small 4 | application that will add an icon to your systray and sit there, regularly 5 | checking if there's anything new for you to upgrade. As soon as it finds 6 | something, it'll show a notification to let you know about it. Very classic 7 | stuff. 8 | 9 | ## What makes kalu any different? 10 | 11 | For starter, **it doesn't need root privileges** to do its checking. Not because 12 | it doesn't synchronize databases, since that would make it mostly useless, but 13 | because it will create a temporary copy of your sync databases, sync those, and 14 | then remove them of course. 15 | 16 | The idea is not only not to require root privileges, but more importantly to 17 | **avoid putting you in a situation where you'd risk messing up your system**, as 18 | you might unknowingly end up basically doing a `pacman -Sy foobar` (which is 19 | pretty generally understood to be a bad idea). 20 | 21 | Because if kalu did sync your databases, and there were upgrades available, but 22 | you did not apply them right away (for one reason or another, e.g. you're busy, 23 | or were AFK when the notification poped up and didn't see it...) then your next 24 | -S operation would really be a -Sy, even though you might not even realize it. 25 | 26 | ## What does it check for? 27 | 28 | kalu can check for a few things : 29 | 30 | - **Arch Linux News**. To be sure not to miss an important announcement from 31 | Arch Linux's official website. 32 | 33 | - **Available upgrades for installed packages**. That is, anything from one of 34 | the repos, or what would be upgraded with a `pacman -Syu` 35 | 36 | - **Available upgrades for non-installed packages**. You can define a list of 37 | "watched packages", that is packages for which you'd like to be notified when 38 | an upgrade is out, even though they're not installed. (E.g. packages you 39 | repack for yourself to apply a patch or something) 40 | 41 | - **Available upgrades for AUR packages**. All foreign packages (i.e. not found 42 | in any repo, aka `-Qm`) can be checked for upgrades available in the AUR. 43 | 44 | - **Available upgrades for watched AUR packages**. Just like with "regular" 45 | packages, you can have a list of packages in the AUR for which you'd like to 46 | be notified when an upgrade is available, even though they're not installed. 47 | 48 | Of course you don't have to use all of this, and you can define which of those 49 | checks kalu should do. Besides maintaining lists of watched (AUR) packages, you 50 | can also define a list of foreign packages that kalu should not check the AUR 51 | for. Since there's no reason to check for packages you know aren't from the AUR 52 | (e.g. packages of your own making). 53 | 54 | ## More than a notifier: kalu's updater 55 | 56 | When a notification is shown, it will feature an action button. This button can 57 | be used to simply trigger a process of your choosing, e.g. you could have it 58 | start pacman with something like `urxvt -e sudo pacman -Syu` 59 | 60 | However, **kalu comes with an integrated system upgrader**, which does exactly 61 | the same, only in a GTK GUI. Before being able to synchronize your databases 62 | (and possibly upgrade the system) the updater needs root privileges, obviously. 63 | 64 | The way it works is: **kalu itself only contains the GUI**, and the part that 65 | does interact with libalpm (to actually upgrade your system) is in a secondary 66 | binary (`kalu-dbus`). This binary only will require root privileges, and will 67 | rely on PolicyKit to ensure you are authorized before doing anything. 68 | 69 | You can also define one or more processes to be run after completing a system 70 | upgrade (to start e.g. 71 | [localepurge](https://aur.archlinux.org/packages.php?ID=11975 "AUR: localepurge: Script to remove disk space wasted for unneeded localizations") 72 | and/or [PkgClip](http://mywaytoarch.tumblr.com/post/16005116198/pkgclip-does-your-pacman-cache-need-a-trim 73 | "PkgClip: Does your pacman cache need a trim?")), and kalu will start them after 74 | each succesfull sysupgrade (and an optional confirmation, which for multiple 75 | processes will feature the full list so you can specify which (if any) to 76 | start). 77 | 78 | Note that if you're not interested in this, you can remove it by specifying 79 | `--disable-updater` on the `configure` command line. 80 | 81 | ## Want to know more? 82 | 83 | Some useful links if you're looking for more info: 84 | 85 | - [blog post about kalu](http://jjacky.com/kalu "kalu @ jjacky.com") 86 | 87 | - [source code & issue tracker](https://github.com/jjk-jacky/kalu "kalu @ GitHub.com") 88 | 89 | - [PKGBUILD in AUR](https://aur.archlinux.org/packages.php?ID=56673 "AUR: kalu") 90 | 91 | Plus, kalu comes with a man page. 92 | -------------------------------------------------------------------------------- /TRANSLATE: -------------------------------------------------------------------------------- 1 | TRANSLATIONS 2 | 3 | Starting with 1.4.0 kalu supports internationalization. One can create a new 4 | translation following these steps : 5 | 6 | 1. Either get the latest tarball of kalu's source code and extract it, or clone 7 | the git repo : 8 | git clone https://github.com/jjk-jacky/kalu.git 9 | 10 | 1b. If you cloned the repo, you'll have to prepare things : 11 | ./autogen.sh 12 | ./configure 13 | 14 | 2. Go inside subfolder "po" 15 | 16 | 2b. If you cloned the repo, you'll have to generate kalu.pot : 17 | make kalu.pot 18 | 19 | 3. Create a new PO file for your locale using msginit : 20 | msginit 21 | If you want to create a translation for another locale than your current one, 22 | you'll simply have to use option -l, e.g. for French (fr) : 23 | msginit -l fr 24 | 25 | 4. Edit the generated .po file, translating each msgid in the corresponding 26 | msgstr. (Also make sure to check the comments on top, including your name, 27 | email, etc. It's also recommended to use UTF-8 as charset.) 28 | 29 | 5. Edit LINGUAS and add the language code (name of the .po file, without .po) 30 | on a new line. 31 | 32 | 6. To test your translation, first make the .gmo file for your translation, e.g: 33 | make fr.gmo 34 | 35 | Then you'll have to build & install kalu, as usual, just start it, and it 36 | should speak your language. Note that if writing a translation for a locale 37 | other than your current one, you'll have to specify it on launch, e.g: 38 | LANG=fr_FR.utf8 kalu 39 | (Also note that you might have to re-generate your locales to include it.) 40 | 41 | 7. When you're satisfied your the translation, simply send it over to have it 42 | included in the next release. You can : 43 | - Fork kalu of github and send a pull request; Or 44 | - Host the .po file somewhere and open an issue with a link; Or 45 | - Send me the file via email 46 | -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # kalu - Copyright (C) 2012-2018 Olivier Brunel 4 | # 5 | # autogen.sh 6 | # Copyright (C) 2012 Olivier Brunel 7 | # Copyright (C) 2003-2012 Sebastien Helleu 8 | # Copyright (C) 2005 Julien Louis 9 | # Copyright (C) 2005-2006 Emmanuel Bouthenot 10 | # 11 | # This file is part of kalu. 12 | # 13 | # kalu is free software: you can redistribute it and/or modify it under the 14 | # terms of the GNU General Public License as published by the Free Software 15 | # Foundation, either version 3 of the License, or (at your option) any later 16 | # version. 17 | # 18 | # kalu is distributed in the hope that it will be useful, but WITHOUT ANY 19 | # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 20 | # FOR A PARTICULAR PURPOSE. 21 | # See the GNU General Public License for more details. 22 | # 23 | # You should have received a copy of the GNU General Public License along with 24 | # kalu. If not, see http://www.gnu.org/licenses/ 25 | 26 | # Based on autogen.sh from WeeChat, http://weechat.org 27 | 28 | LOG=autogen.log 29 | 30 | function abort() 31 | { 32 | echo "An error occured, the output below can be found in $LOG" 33 | echo "-------" 34 | cat $LOG 35 | exit 1 36 | } 37 | 38 | function run() 39 | { 40 | echo -n "Running \"$@\" ... " 41 | echo "$ $@" >>$LOG 42 | eval $@ >>$LOG 2>&1 43 | if [ $? -eq 0 ]; then 44 | echo "OK" 45 | else 46 | echo "FAILED" 47 | abort 48 | fi 49 | } 50 | 51 | if [ -e $LOG ]; then 52 | rm "$LOG" 53 | fi 54 | 55 | run "autopoint" 56 | run "libtoolize --automake --copy" 57 | run "aclocal -I m4" 58 | run "autoheader" 59 | run "autoconf" 60 | run "automake --add-missing --copy" 61 | 62 | echo "done; Full log available in $LOG" 63 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | # -*- Autoconf -*- 2 | # Process this file with autoconf to produce a configure script. 3 | 4 | AC_PREREQ([2.68]) 5 | AC_INIT([kalu], [4.3.0], [jjk@jjacky.com]) 6 | AC_CONFIG_SRCDIR([src/kalu/kalu.h]) 7 | AC_CONFIG_HEADERS([config.h]) 8 | AC_CONFIG_MACRO_DIR([m4]) 9 | AC_CONFIG_AUX_DIR([build-aux]) 10 | 11 | AC_SYS_LARGEFILE 12 | 13 | AM_INIT_AUTOMAKE([-Wall -Werror foreign silent-rules subdir-objects]) 14 | AM_SILENT_RULES([yes]) 15 | 16 | # For automake >= 1.12 17 | m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) 18 | 19 | # Checks for programs. 20 | AC_PROG_CXX 21 | AC_PROG_AWK 22 | AC_PROG_CC_C99 23 | AC_PROG_CPP 24 | AC_PROG_INSTALL 25 | AC_PROG_LN_S 26 | AC_PROG_MAKE_SET 27 | AC_PROG_RANLIB 28 | 29 | AM_PROG_CC_C_O 30 | 31 | LT_INIT 32 | 33 | AM_GNU_GETTEXT([external], [need-ngettext]) 34 | AM_GNU_GETTEXT_VERSION([0.18.1]) 35 | 36 | # Option for News URL 37 | AC_ARG_WITH([news-rss-url], 38 | AC_HELP_STRING([--with-news-rss-url=URL], [set the RSS URL for Arch Linux News]), 39 | [NEWS_RSS_URL=$withval], [NEWS_RSS_URL="https://www.archlinux.org/feeds/news/"]) 40 | 41 | # Options for AUR URL 42 | AC_ARG_WITH([url-aur-prefix], 43 | AC_HELP_STRING([--with-url-aur-prefix=URL], [set the prefix for the AUR URL]), 44 | [AUR_URL_PREFIX=$withval], [AUR_URL_PREFIX="https://aur.archlinux.org/rpc/?v=5&type=info"]) 45 | AC_ARG_WITH([url-aur-prefix-pkg], 46 | AC_HELP_STRING([--with-url-aur-prefix-pkg=PREFIX], 47 | [set the prefix before each package for the AUR URL]), 48 | [AUR_URL_PREFIX_PKG=$withval], [AUR_URL_PREFIX_PKG="&arg[[]]="]) 49 | 50 | # Feature: KDE's StatusNotifierItem 51 | AC_ARG_ENABLE([status-notifier], 52 | AC_HELP_STRING([--enable-status-notifier], 53 | [enable support for KDE StatusNotifierItem]), 54 | if test $enableval = "yes"; then 55 | with_status_notifier=yes 56 | elif test $enableval = "no"; then 57 | with_status_notifier=no 58 | else 59 | AC_MSG_ERROR([Invalid value given to --enable-status-notifier; must be yes or no]) 60 | fi 61 | , 62 | with_status_notifier=no) 63 | AM_CONDITIONAL([ENABLE_STATUS_NOTIFIER], [test "x$with_status_notifier" = "xyes"]) 64 | 65 | # Feature: GUI 66 | AC_ARG_ENABLE([gui], 67 | AC_HELP_STRING([--disable-gui], 68 | [disable kalu GUI (make a CLI-only binary))]), 69 | if test $enableval = "yes"; then 70 | with_gui=yes 71 | elif test $enableval = "no"; then 72 | with_gui=no 73 | else 74 | AC_MSG_ERROR([Invalid value given to --enable-gui; must be yes or no]) 75 | fi 76 | , 77 | with_gui=yes) 78 | AM_CONDITIONAL([DISABLE_GUI], [test "x$with_gui" = "xno"]) 79 | 80 | # Feature: updater (unless GUI was disabled) 81 | if test "x$with_gui" = "xyes"; then 82 | AC_ARG_ENABLE([updater], 83 | AC_HELP_STRING([--disable-updater], 84 | [disable kalu updater (GTK GUI for system upgrade)]), 85 | if test $enableval = "yes"; then 86 | with_updater=yes 87 | elif test $enableval = "no"; then 88 | with_updater=no 89 | else 90 | AC_MSG_ERROR([Invalid value given to --enable-updater; must be yes or no]) 91 | fi 92 | , 93 | with_updater=yes) 94 | else 95 | with_updater=no 96 | fi 97 | AM_CONDITIONAL([DISABLE_UPDATER], [test "x$with_updater" = "xno"]) 98 | 99 | # Group name for not requiring auth to do a sysupgrade 100 | AC_ARG_WITH([sysupgrade-group], 101 | AC_HELP_STRING([--with-sysupgrade-group=GROUP], 102 | [set the GROUP whose members can run sysupgrade without authentication]), 103 | [GROUP=$withval], [GROUP="kalu"]) 104 | AC_SUBST([SYSUPGRADE_GROUP], ["$GROUP"]) 105 | 106 | # Option to use git version 107 | AC_ARG_ENABLE([git-version], 108 | AS_HELP_STRING([--enable-git-version], [enable the use of git version]), 109 | [wantgitver=$enableval], [wantgitver=no]) 110 | 111 | # Enable extra compiler warning flags 112 | AC_ARG_ENABLE([warning-flags], 113 | AS_HELP_STRING([--enable-warning-flags], [enable extra compiler warning flags]), 114 | [warningflags=$enableval], [warningflags=no]) 115 | 116 | # Checks for libraries. 117 | AC_CHECK_LIB([alpm], [alpm_db_get_pkg], , 118 | AC_MSG_ERROR([libalpm is required])) 119 | AC_CHECK_LIB([m], [fabs], , 120 | AC_MSG_ERROR([libm is required])) 121 | AS_IF([test "x$with_gui" = "xyes"], [ 122 | PKG_CHECK_MODULES(NOTIFY, [libnotify], , 123 | AC_MSG_ERROR([libnotify is required])) 124 | if test "x$with_updater" = "xyes"; then 125 | PKG_CHECK_MODULES(POLKIT, [polkit-gobject-1], , 126 | AC_MSG_ERROR([PolicyKit is required (for kalu updater)])) 127 | else 128 | AC_DEFINE([DISABLE_UPDATER], 1, [Disable kalu udpater]) 129 | fi 130 | 131 | # Checks for GTK+3 132 | PKG_CHECK_MODULES(GTK, [gtk+-3.0], , AC_MSG_ERROR([GTK+3 is required])) 133 | 134 | AS_IF([test "x$with_status_notifier" = "xyes"], [ 135 | PKG_CHECK_MODULES(STATUS_NOTIFIER, [statusnotifier], , 136 | AC_MSG_ERROR([statusnotifier is required for StatusNotifierItem support])) 137 | AC_DEFINE([ENABLE_STATUS_NOTIFIER], 1, [Enable StatusNotifierItem]) 138 | ]) 139 | ], [ 140 | AC_DEFINE([DISABLE_GUI], 1, [Disable GUI]) 141 | AC_DEFINE([DISABLE_UPDATER], 1, [Disable kalu udpater]) 142 | # No GTK, check for Glib 143 | PKG_CHECK_MODULES(GLIB2, [glib-2.0 gobject-2.0 gthread-2.0], , 144 | AC_MSG_ERROR([glib2 is required])) 145 | AS_IF([test "x$with_status_notifier" = "xyes"], [ 146 | AC_MSG_ERROR([StatusNotifierItem support requires GUI]) 147 | ]) 148 | ]) 149 | 150 | # Check for libcurl 151 | PKG_CHECK_MODULES(LIBCURL, [libcurl], , AC_MSG_ERROR([libcurl is required])) 152 | 153 | # Checks for header files. 154 | AC_CHECK_HEADERS([fcntl.h float.h libintl.h limits.h locale.h stdlib.h string.h unistd.h utime.h]) 155 | 156 | # Checks for typedefs, structures, and compiler characteristics. 157 | AC_C_INLINE 158 | AC_TYPE_OFF_T 159 | AC_TYPE_SIZE_T 160 | PATH_MAX_DEFINED 161 | 162 | # Checks for library functions. 163 | AC_FUNC_MALLOC 164 | AC_FUNC_REALLOC 165 | AC_CHECK_FUNCS([floor memmove memset mkdir mkfifo pow rmdir select setenv setlocale strchr strdup strerror strrchr strstr uname utime]) 166 | 167 | # Defines some constants 168 | AC_DEFINE_UNQUOTED([KALU_LOGO], 169 | ["$(eval echo $(eval echo ${datadir}))/pixmaps/kalu.png"], 170 | [Path/to/kalu.png]) 171 | AC_DEFINE_UNQUOTED([NEWS_RSS_URL], ["$NEWS_RSS_URL"], 172 | [News RSS URL]) 173 | AC_DEFINE_UNQUOTED([AUR_URL_PREFIX], ["$AUR_URL_PREFIX"], 174 | [Prefix to construct URL for AUR]) 175 | AC_DEFINE_UNQUOTED([AUR_URL_PREFIX_PKG], ["$AUR_URL_PREFIX_PKG"], 176 | [Prefix before each package to construct AUR URL]) 177 | 178 | # git version 179 | AC_MSG_CHECKING([if git version must be used]) 180 | if test "x$wantgitver" = "xyes"; then 181 | AC_MSG_RESULT([yes]) 182 | AC_CHECK_PROGS([GIT], [git]) 183 | if test "x$GIT" = "x"; then 184 | AC_MSG_ERROR([Cannot use git version: git not found]) 185 | fi 186 | AC_CHECK_FILE([.git/], hasgitdir=yes) 187 | if test "x$hasgitdir" = "xyes"; then 188 | usegitver=yes 189 | gitver=-git 190 | AC_DEFINE([USE_GIT_VERSION], , [Use GIT version]) 191 | else 192 | AC_MSG_ERROR([Cannot use git version: .git not found]) 193 | fi 194 | else 195 | AC_MSG_RESULT([no]) 196 | usegitver=no 197 | gitver= 198 | fi 199 | AM_CONDITIONAL(USE_GIT_VERSION, test "x$usegitver" = "xyes") 200 | 201 | # warning flags 202 | WARNING_CFLAGS="-Wall" 203 | AC_MSG_CHECKING([for extra compiler warning flags]) 204 | if test "x$warningflags" = "xyes"; then 205 | AC_MSG_RESULT([yes]) 206 | CFLAGS_ADD([-Wextra], [WARNING_CFLAGS]) 207 | CFLAGS_ADD([-Wshadow], [WARNING_CFLAGS]) 208 | CFLAGS_ADD([-Wpointer-arith], [WARNING_CFLAGS]) 209 | CFLAGS_ADD([-Wcast-align], [WARNING_CFLAGS]) 210 | CFLAGS_ADD([-Wwrite-strings], [WARNING_CFLAGS]) 211 | CFLAGS_ADD([-Wmissing-prototypes], [WARNING_CFLAGS]) 212 | CFLAGS_ADD([-Wmissing-declarations], [WARNING_CFLAGS]) 213 | CFLAGS_ADD([-Wredundant-decls], [WARNING_CFLAGS]) 214 | CFLAGS_ADD([-Wnested-externs], [WARNING_CFLAGS]) 215 | CFLAGS_ADD([-Winline], [WARNING_CFLAGS]) 216 | CFLAGS_ADD([-Wno-long-long], [WARNING_CFLAGS]) 217 | CFLAGS_ADD([-Wuninitialized], [WARNING_CFLAGS]) 218 | CFLAGS_ADD([-Wconversion], [WARNING_CFLAGS]) 219 | CFLAGS_ADD([-Wstrict-prototypes], [WARNING_CFLAGS]) 220 | 221 | CFLAGS_ADD([-Wclobbered], [WARNING_CFLAGS]) 222 | CFLAGS_ADD([-Wempty-body], [WARNING_CFLAGS]) 223 | CFLAGS_ADD([-Wfloat-equal], [WARNING_CFLAGS]) 224 | CFLAGS_ADD([-Wformat-nonliteral], [WARNING_CFLAGS]) 225 | CFLAGS_ADD([-Wformat-security], [WARNING_CFLAGS]) 226 | CFLAGS_ADD([-Wignored-qualifiers], [WARNING_CFLAGS]) 227 | CFLAGS_ADD([-Wlogical-op], [WARNING_CFLAGS]) 228 | CFLAGS_ADD([-Wmissing-field-initializers], [WARNING_CFLAGS]) 229 | CFLAGS_ADD([-Wmissing-parameter-type], [WARNING_CFLAGS]) 230 | CFLAGS_ADD([-Wold-style-declaration], [WARNING_CFLAGS]) 231 | CFLAGS_ADD([-Woverride-init], [WARNING_CFLAGS]) 232 | CFLAGS_ADD([-Wsign-compare], [WARNING_CFLAGS]) 233 | CFLAGS_ADD([-Wstrict-aliasing], [WARNING_CFLAGS]) 234 | CFLAGS_ADD([-Wstrict-overflow=5], [WARNING_CFLAGS]) 235 | CFLAGS_ADD([-Wtype-limits], [WARNING_CFLAGS]) 236 | CFLAGS_ADD([-Wunused-but-set-parameter], [WARNING_CFLAGS]) 237 | CFLAGS_ADD([-Wunused-parameter], [WARNING_CFLAGS]) 238 | else 239 | AC_MSG_RESULT([no]) 240 | fi 241 | 242 | AC_CONFIG_FILES([Makefile po/Makefile.in]) 243 | AC_OUTPUT 244 | 245 | echo " 246 | ${PACKAGE} version ${PACKAGE_VERSION}${gitver} 247 | 248 | Build information: 249 | source code location : ${srcdir} 250 | prefix : ${prefix} 251 | GUI : ${with_gui} 252 | kalu's updater : ${with_updater} 253 | StatusNotifierItem : ${with_status_notifier} 254 | group to not need auth : ${GROUP} 255 | compiler warning flags : ${WARNING_CFLAGS} 256 | 257 | Arch Linux News RSS URL : ${NEWS_RSS_URL} 258 | AUR URL prefix : ${AUR_URL_PREFIX} 259 | AUR URL package prefix : ${AUR_URL_PREFIX_PKG} 260 | 261 | Install paths: 262 | binaries : $(eval echo $(eval echo ${bindir})) 263 | documentation : $(eval echo $(eval echo ${docdir})) 264 | man pages : $(eval echo $(eval echo ${mandir})) 265 | " 266 | -------------------------------------------------------------------------------- /m4/cflagsadd.m4: -------------------------------------------------------------------------------- 1 | dnl CFLAGS_ADD(PARAMETER, VARIABLE) 2 | dnl Adds parameter to VARIABLE if the compiler supports it. For example, 3 | dnl CFLAGS_ADD([-Wall],[WARN_FLAGS]). 4 | AC_DEFUN([CFLAGS_ADD], 5 | [AS_VAR_PUSHDEF([my_cflags], [cflags_cv_warn_$1])dnl 6 | AC_CACHE_CHECK([whether compiler handles $1], [my_cflags], [ 7 | save_CFLAGS="$CFLAGS" 8 | CFLAGS="${CFLAGS} $1" 9 | AC_COMPILE_IFELSE([AC_LANG_PROGRAM([])], 10 | [AS_VAR_SET([my_cflags], [yes])], 11 | [AS_VAR_SET([my_cflags], [no])]) 12 | CFLAGS="$save_CFLAGS" 13 | ]) 14 | AS_VAR_PUSHDEF([new_cflags], [[$2]])dnl 15 | AS_VAR_IF([my_cflags], [yes], [AS_VAR_APPEND([new_cflags], [" $1"])]) 16 | AS_VAR_POPDEF([new_cflags])dnl 17 | AS_VAR_POPDEF([my_cflags])dnl 18 | m4_ifval([$2], [AS_LITERAL_IF([$2], [AC_SUBST([$2])], [])])dnl 19 | ]) 20 | -------------------------------------------------------------------------------- /m4/pathmax.m4: -------------------------------------------------------------------------------- 1 | dnl Checks for PATH_MAX and defines it if not present 2 | AC_DEFUN([PATH_MAX_DEFINED], 3 | [AC_CACHE_CHECK([PATH_MAX defined], path_max_cv_defined, 4 | [AC_EGREP_CPP(yes, [[ 5 | #include 6 | #if defined(PATH_MAX) 7 | yes 8 | #endif 9 | ]], 10 | [path_max_cv_defined=yes], 11 | [path_max_cv_defined=no])] 12 | ) 13 | if test $path_max_cv_defined = no; then 14 | AC_DEFINE([PATH_MAX], 4096, [Define if PATH_MAX is undefined by limits.h.]) 15 | fi 16 | ]) 17 | -------------------------------------------------------------------------------- /m4/po.m4: -------------------------------------------------------------------------------- 1 | # po.m4 serial 17 (gettext-0.18) 2 | dnl Copyright (C) 1995-2010 Free Software Foundation, Inc. 3 | dnl This file is free software; the Free Software Foundation 4 | dnl gives unlimited permission to copy and/or distribute it, 5 | dnl with or without modifications, as long as this notice is preserved. 6 | dnl 7 | dnl This file can can be used in projects which are not available under 8 | dnl the GNU General Public License or the GNU Library General Public 9 | dnl License but which still want to provide support for the GNU gettext 10 | dnl functionality. 11 | dnl Please note that the actual code of the GNU gettext library is covered 12 | dnl by the GNU Library General Public License, and the rest of the GNU 13 | dnl gettext package package is covered by the GNU General Public License. 14 | dnl They are *not* in the public domain. 15 | 16 | dnl Authors: 17 | dnl Ulrich Drepper , 1995-2000. 18 | dnl Bruno Haible , 2000-2003. 19 | 20 | AC_PREREQ([2.50]) 21 | 22 | dnl Checks for all prerequisites of the po subdirectory. 23 | AC_DEFUN([AM_PO_SUBDIRS], 24 | [ 25 | AC_REQUIRE([AC_PROG_MAKE_SET])dnl 26 | AC_REQUIRE([AC_PROG_INSTALL])dnl 27 | AC_REQUIRE([AC_PROG_MKDIR_P])dnl defined by automake 28 | AC_REQUIRE([AM_NLS])dnl 29 | 30 | dnl Release version of the gettext macros. This is used to ensure that 31 | dnl the gettext macros and po/Makefile.in.in are in sync. 32 | AC_SUBST([GETTEXT_MACRO_VERSION], [0.18]) 33 | 34 | dnl Perform the following tests also if --disable-nls has been given, 35 | dnl because they are needed for "make dist" to work. 36 | 37 | dnl Search for GNU msgfmt in the PATH. 38 | dnl The first test excludes Solaris msgfmt and early GNU msgfmt versions. 39 | dnl The second test excludes FreeBSD msgfmt. 40 | AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, 41 | [$ac_dir/$ac_word --statistics /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1 && 42 | (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], 43 | :) 44 | AC_PATH_PROG([GMSGFMT], [gmsgfmt], [$MSGFMT]) 45 | 46 | dnl Test whether it is GNU msgfmt >= 0.15. 47 | changequote(,)dnl 48 | case `$MSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in 49 | '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) MSGFMT_015=: ;; 50 | *) MSGFMT_015=$MSGFMT ;; 51 | esac 52 | changequote([,])dnl 53 | AC_SUBST([MSGFMT_015]) 54 | changequote(,)dnl 55 | case `$GMSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in 56 | '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) GMSGFMT_015=: ;; 57 | *) GMSGFMT_015=$GMSGFMT ;; 58 | esac 59 | changequote([,])dnl 60 | AC_SUBST([GMSGFMT_015]) 61 | 62 | dnl Search for GNU xgettext 0.12 or newer in the PATH. 63 | dnl The first test excludes Solaris xgettext and early GNU xgettext versions. 64 | dnl The second test excludes FreeBSD xgettext. 65 | AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, 66 | [$ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1 && 67 | (if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], 68 | :) 69 | dnl Remove leftover from FreeBSD xgettext call. 70 | rm -f messages.po 71 | 72 | dnl Test whether it is GNU xgettext >= 0.15. 73 | changequote(,)dnl 74 | case `$XGETTEXT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in 75 | '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) XGETTEXT_015=: ;; 76 | *) XGETTEXT_015=$XGETTEXT ;; 77 | esac 78 | changequote([,])dnl 79 | AC_SUBST([XGETTEXT_015]) 80 | 81 | dnl Search for GNU msgmerge 0.11 or newer in the PATH. 82 | AM_PATH_PROG_WITH_TEST(MSGMERGE, msgmerge, 83 | [$ac_dir/$ac_word --update -q /dev/null /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1], :) 84 | 85 | dnl Installation directories. 86 | dnl Autoconf >= 2.60 defines localedir. For older versions of autoconf, we 87 | dnl have to define it here, so that it can be used in po/Makefile. 88 | test -n "$localedir" || localedir='${datadir}/locale' 89 | AC_SUBST([localedir]) 90 | 91 | dnl Support for AM_XGETTEXT_OPTION. 92 | test -n "${XGETTEXT_EXTRA_OPTIONS+set}" || XGETTEXT_EXTRA_OPTIONS= 93 | AC_SUBST([XGETTEXT_EXTRA_OPTIONS]) 94 | 95 | AC_CONFIG_COMMANDS([po-directories], [[ 96 | for ac_file in $CONFIG_FILES; do 97 | # Support "outfile[:infile[:infile...]]" 98 | case "$ac_file" in 99 | *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; 100 | esac 101 | # PO directories have a Makefile.in generated from Makefile.in.in. 102 | case "$ac_file" in */Makefile.in) 103 | # Adjust a relative srcdir. 104 | ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` 105 | ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`" 106 | ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` 107 | # In autoconf-2.13 it is called $ac_given_srcdir. 108 | # In autoconf-2.50 it is called $srcdir. 109 | test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" 110 | case "$ac_given_srcdir" in 111 | .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; 112 | /*) top_srcdir="$ac_given_srcdir" ;; 113 | *) top_srcdir="$ac_dots$ac_given_srcdir" ;; 114 | esac 115 | # Treat a directory as a PO directory if and only if it has a 116 | # POTFILES.in file. This allows packages to have multiple PO 117 | # directories under different names or in different locations. 118 | if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then 119 | rm -f "$ac_dir/POTFILES" 120 | test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES" 121 | cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES" 122 | POMAKEFILEDEPS="POTFILES.in" 123 | # ALL_LINGUAS, POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES depend 124 | # on $ac_dir but don't depend on user-specified configuration 125 | # parameters. 126 | if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then 127 | # The LINGUAS file contains the set of available languages. 128 | if test -n "$OBSOLETE_ALL_LINGUAS"; then 129 | test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete" 130 | fi 131 | ALL_LINGUAS_=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"` 132 | # Hide the ALL_LINGUAS assigment from automake < 1.5. 133 | eval 'ALL_LINGUAS''=$ALL_LINGUAS_' 134 | POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS" 135 | else 136 | # The set of available languages was given in configure.in. 137 | # Hide the ALL_LINGUAS assigment from automake < 1.5. 138 | eval 'ALL_LINGUAS''=$OBSOLETE_ALL_LINGUAS' 139 | fi 140 | # Compute POFILES 141 | # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po) 142 | # Compute UPDATEPOFILES 143 | # as $(foreach lang, $(ALL_LINGUAS), $(lang).po-update) 144 | # Compute DUMMYPOFILES 145 | # as $(foreach lang, $(ALL_LINGUAS), $(lang).nop) 146 | # Compute GMOFILES 147 | # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo) 148 | case "$ac_given_srcdir" in 149 | .) srcdirpre= ;; 150 | *) srcdirpre='$(srcdir)/' ;; 151 | esac 152 | POFILES= 153 | UPDATEPOFILES= 154 | DUMMYPOFILES= 155 | GMOFILES= 156 | for lang in $ALL_LINGUAS; do 157 | POFILES="$POFILES $srcdirpre$lang.po" 158 | UPDATEPOFILES="$UPDATEPOFILES $lang.po-update" 159 | DUMMYPOFILES="$DUMMYPOFILES $lang.nop" 160 | GMOFILES="$GMOFILES $srcdirpre$lang.gmo" 161 | done 162 | # CATALOGS depends on both $ac_dir and the user's LINGUAS 163 | # environment variable. 164 | INST_LINGUAS= 165 | if test -n "$ALL_LINGUAS"; then 166 | for presentlang in $ALL_LINGUAS; do 167 | useit=no 168 | if test "%UNSET%" != "$LINGUAS"; then 169 | desiredlanguages="$LINGUAS" 170 | else 171 | desiredlanguages="$ALL_LINGUAS" 172 | fi 173 | for desiredlang in $desiredlanguages; do 174 | # Use the presentlang catalog if desiredlang is 175 | # a. equal to presentlang, or 176 | # b. a variant of presentlang (because in this case, 177 | # presentlang can be used as a fallback for messages 178 | # which are not translated in the desiredlang catalog). 179 | case "$desiredlang" in 180 | "$presentlang"*) useit=yes;; 181 | esac 182 | done 183 | if test $useit = yes; then 184 | INST_LINGUAS="$INST_LINGUAS $presentlang" 185 | fi 186 | done 187 | fi 188 | CATALOGS= 189 | if test -n "$INST_LINGUAS"; then 190 | for lang in $INST_LINGUAS; do 191 | CATALOGS="$CATALOGS $lang.gmo" 192 | done 193 | fi 194 | test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile" 195 | sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@POMAKEFILEDEPS@|$POMAKEFILEDEPS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile" 196 | for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do 197 | if test -f "$f"; then 198 | case "$f" in 199 | *.orig | *.bak | *~) ;; 200 | *) cat "$f" >> "$ac_dir/Makefile" ;; 201 | esac 202 | fi 203 | done 204 | fi 205 | ;; 206 | esac 207 | done]], 208 | [# Capture the value of obsolete ALL_LINGUAS because we need it to compute 209 | # POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES, CATALOGS. But hide it 210 | # from automake < 1.5. 211 | eval 'OBSOLETE_ALL_LINGUAS''="$ALL_LINGUAS"' 212 | # Capture the value of LINGUAS because we need it to compute CATALOGS. 213 | LINGUAS="${LINGUAS-%UNSET%}" 214 | ]) 215 | ]) 216 | 217 | dnl Postprocesses a Makefile in a directory containing PO files. 218 | AC_DEFUN([AM_POSTPROCESS_PO_MAKEFILE], 219 | [ 220 | # When this code is run, in config.status, two variables have already been 221 | # set: 222 | # - OBSOLETE_ALL_LINGUAS is the value of LINGUAS set in configure.in, 223 | # - LINGUAS is the value of the environment variable LINGUAS at configure 224 | # time. 225 | 226 | changequote(,)dnl 227 | # Adjust a relative srcdir. 228 | ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` 229 | ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`" 230 | ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` 231 | # In autoconf-2.13 it is called $ac_given_srcdir. 232 | # In autoconf-2.50 it is called $srcdir. 233 | test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" 234 | case "$ac_given_srcdir" in 235 | .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; 236 | /*) top_srcdir="$ac_given_srcdir" ;; 237 | *) top_srcdir="$ac_dots$ac_given_srcdir" ;; 238 | esac 239 | 240 | # Find a way to echo strings without interpreting backslash. 241 | if test "X`(echo '\t') 2>/dev/null`" = 'X\t'; then 242 | gt_echo='echo' 243 | else 244 | if test "X`(printf '%s\n' '\t') 2>/dev/null`" = 'X\t'; then 245 | gt_echo='printf %s\n' 246 | else 247 | echo_func () { 248 | cat < "$ac_file.tmp" 408 | if grep -l '@TCLCATALOGS@' "$ac_file" > /dev/null; then 409 | # Add dependencies that cannot be formulated as a simple suffix rule. 410 | for lang in $ALL_LINGUAS; do 411 | frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'` 412 | cat >> "$ac_file.tmp" < /dev/null; then 420 | # Add dependencies that cannot be formulated as a simple suffix rule. 421 | for lang in $ALL_LINGUAS; do 422 | frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e 's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e 's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'` 423 | cat >> "$ac_file.tmp" <> "$ac_file.tmp" < 2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /misc/org.jjk.kalu.policy: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | jjacky 7 | https://github.com/jjk-jacky 8 | 9 | 10 | Upgrade all packages that are out of date (same as `pacman -Syu`) 11 | Authentication is required to start a full system upgrade via kalu's updater 12 | kalu 13 | 14 | auth_admin 15 | auth_admin 16 | auth_admin 17 | 18 | 19 | 20 | 21 | Download all packages that are out of date (similar to `pacman -Syuw`) 22 | Authentication is required to download packages to pacman's cache (system databases won't be touched/synchonized) 23 | kalu 24 | 25 | auth_admin 26 | auth_admin 27 | auth_admin 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /misc/org.jjk.kalu.service.tpl: -------------------------------------------------------------------------------- 1 | [D-BUS Service] 2 | Name=org.jjk.kalu 3 | Exec=@BINDIR@/kalu-dbus-launcher 4 | User=root 5 | -------------------------------------------------------------------------------- /po/.gitignore: -------------------------------------------------------------------------------- 1 | *.gmo 2 | POTFILES 3 | kalu.pot 4 | remove-potcdate.sed 5 | stamp-po 6 | -------------------------------------------------------------------------------- /po/LINGUAS: -------------------------------------------------------------------------------- 1 | # Available languages 2 | fr 3 | nb 4 | es -------------------------------------------------------------------------------- /po/Makefile.in.in: -------------------------------------------------------------------------------- 1 | # Makefile for PO directory in any package using GNU gettext. 2 | # Copyright (C) 1995-1997, 2000-2007, 2009-2010 by Ulrich Drepper 3 | # 4 | # This file can be copied and used freely without restrictions. It can 5 | # be used in projects which are not available under the GNU General Public 6 | # License but which still want to provide support for the GNU gettext 7 | # functionality. 8 | # Please note that the actual code of GNU gettext is covered by the GNU 9 | # General Public License and is *not* in the public domain. 10 | # 11 | # Origin: gettext-0.18 12 | GETTEXT_MACRO_VERSION = 0.18 13 | 14 | PACKAGE = @PACKAGE@ 15 | VERSION = @VERSION@ 16 | PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ 17 | 18 | SHELL = /bin/sh 19 | @SET_MAKE@ 20 | 21 | srcdir = @srcdir@ 22 | top_srcdir = @top_srcdir@ 23 | VPATH = @srcdir@ 24 | 25 | prefix = @prefix@ 26 | exec_prefix = @exec_prefix@ 27 | datarootdir = @datarootdir@ 28 | datadir = @datadir@ 29 | localedir = @localedir@ 30 | gettextsrcdir = $(datadir)/gettext/po 31 | 32 | INSTALL = @INSTALL@ 33 | INSTALL_DATA = @INSTALL_DATA@ 34 | 35 | # We use $(mkdir_p). 36 | # In automake <= 1.9.x, $(mkdir_p) is defined either as "mkdir -p --" or as 37 | # "$(mkinstalldirs)" or as "$(install_sh) -d". For these automake versions, 38 | # @install_sh@ does not start with $(SHELL), so we add it. 39 | # In automake >= 1.10, @mkdir_p@ is derived from ${MKDIR_P}, which is defined 40 | # either as "/path/to/mkdir -p" or ".../install-sh -c -d". For these automake 41 | # versions, $(mkinstalldirs) and $(install_sh) are unused. 42 | mkinstalldirs = $(SHELL) @install_sh@ -d 43 | install_sh = $(SHELL) @install_sh@ 44 | MKDIR_P = @MKDIR_P@ 45 | mkdir_p = @mkdir_p@ 46 | 47 | GMSGFMT_ = @GMSGFMT@ 48 | GMSGFMT_no = @GMSGFMT@ 49 | GMSGFMT_yes = @GMSGFMT_015@ 50 | GMSGFMT = $(GMSGFMT_$(USE_MSGCTXT)) 51 | MSGFMT_ = @MSGFMT@ 52 | MSGFMT_no = @MSGFMT@ 53 | MSGFMT_yes = @MSGFMT_015@ 54 | MSGFMT = $(MSGFMT_$(USE_MSGCTXT)) 55 | XGETTEXT_ = @XGETTEXT@ 56 | XGETTEXT_no = @XGETTEXT@ 57 | XGETTEXT_yes = @XGETTEXT_015@ 58 | XGETTEXT = $(XGETTEXT_$(USE_MSGCTXT)) 59 | MSGMERGE = msgmerge 60 | MSGMERGE_UPDATE = @MSGMERGE@ --update 61 | MSGINIT = msginit 62 | MSGCONV = msgconv 63 | MSGFILTER = msgfilter 64 | 65 | POFILES = @POFILES@ 66 | GMOFILES = @GMOFILES@ 67 | UPDATEPOFILES = @UPDATEPOFILES@ 68 | DUMMYPOFILES = @DUMMYPOFILES@ 69 | DISTFILES.common = Makefile.in.in remove-potcdate.sin \ 70 | $(DISTFILES.common.extra1) $(DISTFILES.common.extra2) $(DISTFILES.common.extra3) 71 | DISTFILES = $(DISTFILES.common) Makevars POTFILES.in \ 72 | $(POFILES) $(GMOFILES) \ 73 | $(DISTFILES.extra1) $(DISTFILES.extra2) $(DISTFILES.extra3) 74 | 75 | POTFILES = \ 76 | 77 | CATALOGS = @CATALOGS@ 78 | 79 | # Makevars gets inserted here. (Don't remove this line!) 80 | 81 | .SUFFIXES: 82 | .SUFFIXES: .po .gmo .mo .sed .sin .nop .po-create .po-update 83 | 84 | .po.mo: 85 | @echo "$(MSGFMT) -c -o $@ $<"; \ 86 | $(MSGFMT) -c -o t-$@ $< && mv t-$@ $@ 87 | 88 | .po.gmo: 89 | @lang=`echo $* | sed -e 's,.*/,,'`; \ 90 | test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ 91 | echo "$${cdcmd}rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics --verbose -o $${lang}.gmo $${lang}.po"; \ 92 | cd $(srcdir) && rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics --verbose -o t-$${lang}.gmo $${lang}.po && mv t-$${lang}.gmo $${lang}.gmo 93 | 94 | .sin.sed: 95 | sed -e '/^#/d' $< > t-$@ 96 | mv t-$@ $@ 97 | 98 | 99 | all: check-macro-version all-@USE_NLS@ 100 | 101 | all-yes: stamp-po 102 | all-no: 103 | 104 | # Ensure that the gettext macros and this Makefile.in.in are in sync. 105 | check-macro-version: 106 | @test "$(GETTEXT_MACRO_VERSION)" = "@GETTEXT_MACRO_VERSION@" \ 107 | || { echo "*** error: gettext infrastructure mismatch: using a Makefile.in.in from gettext version $(GETTEXT_MACRO_VERSION) but the autoconf macros are from gettext version @GETTEXT_MACRO_VERSION@" 1>&2; \ 108 | exit 1; \ 109 | } 110 | 111 | # $(srcdir)/$(DOMAIN).pot is only created when needed. When xgettext finds no 112 | # internationalized messages, no $(srcdir)/$(DOMAIN).pot is created (because 113 | # we don't want to bother translators with empty POT files). We assume that 114 | # LINGUAS is empty in this case, i.e. $(POFILES) and $(GMOFILES) are empty. 115 | # In this case, stamp-po is a nop (i.e. a phony target). 116 | 117 | # stamp-po is a timestamp denoting the last time at which the CATALOGS have 118 | # been loosely updated. Its purpose is that when a developer or translator 119 | # checks out the package via CVS, and the $(DOMAIN).pot file is not in CVS, 120 | # "make" will update the $(DOMAIN).pot and the $(CATALOGS), but subsequent 121 | # invocations of "make" will do nothing. This timestamp would not be necessary 122 | # if updating the $(CATALOGS) would always touch them; however, the rule for 123 | # $(POFILES) has been designed to not touch files that don't need to be 124 | # changed. 125 | stamp-po: $(srcdir)/$(DOMAIN).pot 126 | test ! -f $(srcdir)/$(DOMAIN).pot || \ 127 | test -z "$(GMOFILES)" || $(MAKE) $(GMOFILES) 128 | @test ! -f $(srcdir)/$(DOMAIN).pot || { \ 129 | echo "touch stamp-po" && \ 130 | echo timestamp > stamp-poT && \ 131 | mv stamp-poT stamp-po; \ 132 | } 133 | 134 | # Note: Target 'all' must not depend on target '$(DOMAIN).pot-update', 135 | # otherwise packages like GCC can not be built if only parts of the source 136 | # have been downloaded. 137 | 138 | # This target rebuilds $(DOMAIN).pot; it is an expensive operation. 139 | # Note that $(DOMAIN).pot is not touched if it doesn't need to be changed. 140 | $(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in remove-potcdate.sed 141 | if LC_ALL=C grep 'GNU @PACKAGE@' $(top_srcdir)/* 2>/dev/null | grep -v 'libtool:' >/dev/null; then \ 142 | package_gnu='GNU '; \ 143 | else \ 144 | package_gnu=''; \ 145 | fi; \ 146 | if test -n '$(MSGID_BUGS_ADDRESS)' || test '$(PACKAGE_BUGREPORT)' = '@'PACKAGE_BUGREPORT'@'; then \ 147 | msgid_bugs_address='$(MSGID_BUGS_ADDRESS)'; \ 148 | else \ 149 | msgid_bugs_address='$(PACKAGE_BUGREPORT)'; \ 150 | fi; \ 151 | case `$(XGETTEXT) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \ 152 | '' | 0.[0-9] | 0.[0-9].* | 0.1[0-5] | 0.1[0-5].* | 0.16 | 0.16.[0-1]*) \ 153 | $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \ 154 | --add-comments=TRANSLATORS: $(XGETTEXT_OPTIONS) @XGETTEXT_EXTRA_OPTIONS@ \ 155 | --files-from=$(srcdir)/POTFILES.in \ 156 | --copyright-holder='$(COPYRIGHT_HOLDER)' \ 157 | --msgid-bugs-address="$$msgid_bugs_address" \ 158 | ;; \ 159 | *) \ 160 | $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \ 161 | --add-comments=TRANSLATORS: $(XGETTEXT_OPTIONS) @XGETTEXT_EXTRA_OPTIONS@ \ 162 | --files-from=$(srcdir)/POTFILES.in \ 163 | --copyright-holder='$(COPYRIGHT_HOLDER)' \ 164 | --package-name="$${package_gnu}@PACKAGE@" \ 165 | --package-version='@VERSION@' \ 166 | --msgid-bugs-address="$$msgid_bugs_address" \ 167 | ;; \ 168 | esac 169 | test ! -f $(DOMAIN).po || { \ 170 | if test -f $(srcdir)/$(DOMAIN).pot; then \ 171 | sed -f remove-potcdate.sed < $(srcdir)/$(DOMAIN).pot > $(DOMAIN).1po && \ 172 | sed -f remove-potcdate.sed < $(DOMAIN).po > $(DOMAIN).2po && \ 173 | if cmp $(DOMAIN).1po $(DOMAIN).2po >/dev/null 2>&1; then \ 174 | rm -f $(DOMAIN).1po $(DOMAIN).2po $(DOMAIN).po; \ 175 | else \ 176 | rm -f $(DOMAIN).1po $(DOMAIN).2po $(srcdir)/$(DOMAIN).pot && \ 177 | mv $(DOMAIN).po $(srcdir)/$(DOMAIN).pot; \ 178 | fi; \ 179 | else \ 180 | mv $(DOMAIN).po $(srcdir)/$(DOMAIN).pot; \ 181 | fi; \ 182 | } 183 | 184 | # This rule has no dependencies: we don't need to update $(DOMAIN).pot at 185 | # every "make" invocation, only create it when it is missing. 186 | # Only "make $(DOMAIN).pot-update" or "make dist" will force an update. 187 | $(srcdir)/$(DOMAIN).pot: 188 | $(MAKE) $(DOMAIN).pot-update 189 | 190 | # This target rebuilds a PO file if $(DOMAIN).pot has changed. 191 | # Note that a PO file is not touched if it doesn't need to be changed. 192 | $(POFILES): $(srcdir)/$(DOMAIN).pot 193 | @lang=`echo $@ | sed -e 's,.*/,,' -e 's/\.po$$//'`; \ 194 | if test -f "$(srcdir)/$${lang}.po"; then \ 195 | test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ 196 | echo "$${cdcmd}$(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) --lang=$${lang} $${lang}.po $(DOMAIN).pot"; \ 197 | cd $(srcdir) \ 198 | && { case `$(MSGMERGE_UPDATE) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \ 199 | '' | 0.[0-9] | 0.[0-9].* | 0.1[0-7] | 0.1[0-7].*) \ 200 | $(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) $${lang}.po $(DOMAIN).pot;; \ 201 | *) \ 202 | $(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) --lang=$${lang} $${lang}.po $(DOMAIN).pot;; \ 203 | esac; \ 204 | }; \ 205 | else \ 206 | $(MAKE) $${lang}.po-create; \ 207 | fi 208 | 209 | 210 | install: install-exec install-data 211 | install-exec: 212 | install-data: install-data-@USE_NLS@ 213 | if test "$(PACKAGE)" = "gettext-tools"; then \ 214 | $(mkdir_p) $(DESTDIR)$(gettextsrcdir); \ 215 | for file in $(DISTFILES.common) Makevars.template; do \ 216 | $(INSTALL_DATA) $(srcdir)/$$file \ 217 | $(DESTDIR)$(gettextsrcdir)/$$file; \ 218 | done; \ 219 | for file in Makevars; do \ 220 | rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \ 221 | done; \ 222 | else \ 223 | : ; \ 224 | fi 225 | install-data-no: all 226 | install-data-yes: all 227 | @catalogs='$(CATALOGS)'; \ 228 | for cat in $$catalogs; do \ 229 | cat=`basename $$cat`; \ 230 | lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ 231 | dir=$(localedir)/$$lang/LC_MESSAGES; \ 232 | $(mkdir_p) $(DESTDIR)$$dir; \ 233 | if test -r $$cat; then realcat=$$cat; else realcat=$(srcdir)/$$cat; fi; \ 234 | $(INSTALL_DATA) $$realcat $(DESTDIR)$$dir/$(DOMAIN).mo; \ 235 | echo "installing $$realcat as $(DESTDIR)$$dir/$(DOMAIN).mo"; \ 236 | for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \ 237 | if test -n "$$lc"; then \ 238 | if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \ 239 | link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \ 240 | mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ 241 | mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ 242 | (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \ 243 | for file in *; do \ 244 | if test -f $$file; then \ 245 | ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \ 246 | fi; \ 247 | done); \ 248 | rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ 249 | else \ 250 | if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \ 251 | :; \ 252 | else \ 253 | rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \ 254 | mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ 255 | fi; \ 256 | fi; \ 257 | rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ 258 | ln -s ../LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \ 259 | ln $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \ 260 | cp -p $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ 261 | echo "installing $$realcat link as $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo"; \ 262 | fi; \ 263 | done; \ 264 | done 265 | 266 | install-strip: install 267 | 268 | installdirs: installdirs-exec installdirs-data 269 | installdirs-exec: 270 | installdirs-data: installdirs-data-@USE_NLS@ 271 | if test "$(PACKAGE)" = "gettext-tools"; then \ 272 | $(mkdir_p) $(DESTDIR)$(gettextsrcdir); \ 273 | else \ 274 | : ; \ 275 | fi 276 | installdirs-data-no: 277 | installdirs-data-yes: 278 | @catalogs='$(CATALOGS)'; \ 279 | for cat in $$catalogs; do \ 280 | cat=`basename $$cat`; \ 281 | lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ 282 | dir=$(localedir)/$$lang/LC_MESSAGES; \ 283 | $(mkdir_p) $(DESTDIR)$$dir; \ 284 | for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \ 285 | if test -n "$$lc"; then \ 286 | if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \ 287 | link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \ 288 | mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ 289 | mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ 290 | (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \ 291 | for file in *; do \ 292 | if test -f $$file; then \ 293 | ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \ 294 | fi; \ 295 | done); \ 296 | rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ 297 | else \ 298 | if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \ 299 | :; \ 300 | else \ 301 | rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \ 302 | mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ 303 | fi; \ 304 | fi; \ 305 | fi; \ 306 | done; \ 307 | done 308 | 309 | # Define this as empty until I found a useful application. 310 | installcheck: 311 | 312 | uninstall: uninstall-exec uninstall-data 313 | uninstall-exec: 314 | uninstall-data: uninstall-data-@USE_NLS@ 315 | if test "$(PACKAGE)" = "gettext-tools"; then \ 316 | for file in $(DISTFILES.common) Makevars.template; do \ 317 | rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \ 318 | done; \ 319 | else \ 320 | : ; \ 321 | fi 322 | uninstall-data-no: 323 | uninstall-data-yes: 324 | catalogs='$(CATALOGS)'; \ 325 | for cat in $$catalogs; do \ 326 | cat=`basename $$cat`; \ 327 | lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ 328 | for lc in LC_MESSAGES $(EXTRA_LOCALE_CATEGORIES); do \ 329 | rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ 330 | done; \ 331 | done 332 | 333 | check: all 334 | 335 | info dvi ps pdf html tags TAGS ctags CTAGS ID: 336 | 337 | mostlyclean: 338 | rm -f remove-potcdate.sed 339 | rm -f stamp-poT 340 | rm -f core core.* $(DOMAIN).po $(DOMAIN).1po $(DOMAIN).2po *.new.po 341 | rm -fr *.o 342 | 343 | clean: mostlyclean 344 | 345 | distclean: clean 346 | rm -f Makefile Makefile.in POTFILES *.mo 347 | 348 | maintainer-clean: distclean 349 | @echo "This command is intended for maintainers to use;" 350 | @echo "it deletes files that may require special tools to rebuild." 351 | rm -f stamp-po $(GMOFILES) 352 | 353 | distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) 354 | dist distdir: 355 | $(MAKE) update-po 356 | @$(MAKE) dist2 357 | # This is a separate target because 'update-po' must be executed before. 358 | dist2: stamp-po $(DISTFILES) 359 | dists="$(DISTFILES)"; \ 360 | if test "$(PACKAGE)" = "gettext-tools"; then \ 361 | dists="$$dists Makevars.template"; \ 362 | fi; \ 363 | if test -f $(srcdir)/$(DOMAIN).pot; then \ 364 | dists="$$dists $(DOMAIN).pot stamp-po"; \ 365 | fi; \ 366 | if test -f $(srcdir)/ChangeLog; then \ 367 | dists="$$dists ChangeLog"; \ 368 | fi; \ 369 | for i in 0 1 2 3 4 5 6 7 8 9; do \ 370 | if test -f $(srcdir)/ChangeLog.$$i; then \ 371 | dists="$$dists ChangeLog.$$i"; \ 372 | fi; \ 373 | done; \ 374 | if test -f $(srcdir)/LINGUAS; then dists="$$dists LINGUAS"; fi; \ 375 | for file in $$dists; do \ 376 | if test -f $$file; then \ 377 | cp -p $$file $(distdir) || exit 1; \ 378 | else \ 379 | cp -p $(srcdir)/$$file $(distdir) || exit 1; \ 380 | fi; \ 381 | done 382 | 383 | update-po: Makefile 384 | $(MAKE) $(DOMAIN).pot-update 385 | test -z "$(UPDATEPOFILES)" || $(MAKE) $(UPDATEPOFILES) 386 | $(MAKE) update-gmo 387 | 388 | # General rule for creating PO files. 389 | 390 | .nop.po-create: 391 | @lang=`echo $@ | sed -e 's/\.po-create$$//'`; \ 392 | echo "File $$lang.po does not exist. If you are a translator, you can create it through 'msginit'." 1>&2; \ 393 | exit 1 394 | 395 | # General rule for updating PO files. 396 | 397 | .nop.po-update: 398 | @lang=`echo $@ | sed -e 's/\.po-update$$//'`; \ 399 | if test "$(PACKAGE)" = "gettext-tools"; then PATH=`pwd`/../src:$$PATH; fi; \ 400 | tmpdir=`pwd`; \ 401 | echo "$$lang:"; \ 402 | test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ 403 | echo "$${cdcmd}$(MSGMERGE) $(MSGMERGE_OPTIONS) --lang=$$lang $$lang.po $(DOMAIN).pot -o $$lang.new.po"; \ 404 | cd $(srcdir); \ 405 | if { case `$(MSGMERGE) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \ 406 | '' | 0.[0-9] | 0.[0-9].* | 0.1[0-7] | 0.1[0-7].*) \ 407 | $(MSGMERGE) $(MSGMERGE_OPTIONS) -o $$tmpdir/$$lang.new.po $$lang.po $(DOMAIN).pot;; \ 408 | *) \ 409 | $(MSGMERGE) $(MSGMERGE_OPTIONS) --lang=$$lang -o $$tmpdir/$$lang.new.po $$lang.po $(DOMAIN).pot;; \ 410 | esac; \ 411 | }; then \ 412 | if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \ 413 | rm -f $$tmpdir/$$lang.new.po; \ 414 | else \ 415 | if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \ 416 | :; \ 417 | else \ 418 | echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \ 419 | exit 1; \ 420 | fi; \ 421 | fi; \ 422 | else \ 423 | echo "msgmerge for $$lang.po failed!" 1>&2; \ 424 | rm -f $$tmpdir/$$lang.new.po; \ 425 | fi 426 | 427 | $(DUMMYPOFILES): 428 | 429 | update-gmo: Makefile $(GMOFILES) 430 | @: 431 | 432 | # Recreate Makefile by invoking config.status. Explicitly invoke the shell, 433 | # because execution permission bits may not work on the current file system. 434 | # Use @SHELL@, which is the shell determined by autoconf for the use by its 435 | # scripts, not $(SHELL) which is hardwired to /bin/sh and may be deficient. 436 | Makefile: Makefile.in.in Makevars $(top_builddir)/config.status @POMAKEFILEDEPS@ 437 | cd $(top_builddir) \ 438 | && @SHELL@ ./config.status $(subdir)/$@.in po-directories 439 | 440 | force: 441 | 442 | # Tell versions [3.59,3.63) of GNU make not to export all variables. 443 | # Otherwise a system limit (for SysV at least) may be exceeded. 444 | .NOEXPORT: 445 | -------------------------------------------------------------------------------- /po/Makevars: -------------------------------------------------------------------------------- 1 | # Makefile variables for PO directory in any package using GNU gettext. 2 | 3 | # Usually the message domain is the same as the package name. 4 | DOMAIN = $(PACKAGE) 5 | 6 | # These two variables depend on the location of this directory. 7 | subdir = po 8 | top_builddir = .. 9 | 10 | # These options get passed to xgettext. 11 | XGETTEXT_OPTIONS = --keyword=_ --keyword=N_ \ 12 | --keyword=_c:1c,2 \ 13 | --keyword=_n:1,2 --flag=_n:1:c-format --flag=_n:2:c-format 14 | 15 | # This is the copyright holder that gets inserted into the header of the 16 | # $(DOMAIN).pot file. Set this to the copyright holder of the surrounding 17 | # package. (Note that the msgstr strings, extracted from the package's 18 | # sources, belong to the copyright holder of the package.) Translators are 19 | # expected to transfer the copyright for their translations to this person 20 | # or entity, or to disclaim their copyright. The empty string stands for 21 | # the public domain; in this case the translators are expected to disclaim 22 | # their copyright. 23 | COPYRIGHT_HOLDER = Olivier Brunel 24 | 25 | # This is the email address or URL to which the translators shall report 26 | # bugs in the untranslated strings: 27 | # - Strings which are not entire sentences, see the maintainer guidelines 28 | # in the GNU gettext documentation, section 'Preparing Strings'. 29 | # - Strings which use unclear terms or require additional context to be 30 | # understood. 31 | # - Strings which make invalid assumptions about notation of date, time or 32 | # money. 33 | # - Pluralisation problems. 34 | # - Incorrect English spelling. 35 | # - Incorrect formatting. 36 | # It can be your email address, or a mailing list address where translators 37 | # can write to without being subscribed, or the URL of a web page through 38 | # which the translators can contact you. 39 | MSGID_BUGS_ADDRESS = https://github.com/jjk-jacky/kalu/issues 40 | 41 | # This is the list of locale categories, beyond LC_MESSAGES, for which the 42 | # message catalogs shall be used. It is usually empty. 43 | EXTRA_LOCALE_CATEGORIES = 44 | -------------------------------------------------------------------------------- /po/POTFILES.in: -------------------------------------------------------------------------------- 1 | # List of source files which contain translatable strings. 2 | src/kalu/aur.c 3 | src/kalu/conf.c 4 | src/kalu/curl.c 5 | src/kalu/gui.c 6 | src/kalu/kalu-alpm.c 7 | src/kalu/kalu-updater.c 8 | src/kalu/main.c 9 | src/kalu/news.c 10 | src/kalu/preferences.c 11 | src/kalu/shared.c 12 | src/kalu/updater.c 13 | src/kalu/util.c 14 | src/kalu/util-gtk.c 15 | src/kalu/watched.c 16 | 17 | src/kalu-dbus/kalu-dbus.c 18 | -------------------------------------------------------------------------------- /po/remove-potcdate.sin: -------------------------------------------------------------------------------- 1 | # Sed script that remove the POT-Creation-Date line in the header entry 2 | # from a POT file. 3 | # 4 | # The distinction between the first and the following occurrences of the 5 | # pattern is achieved by looking at the hold space. 6 | /^"POT-Creation-Date: .*"$/{ 7 | x 8 | # Test if the hold space is empty. 9 | s/P/P/ 10 | ta 11 | # Yes it was empty. First occurrence. Remove the line. 12 | g 13 | d 14 | bb 15 | :a 16 | # The hold space was nonempty. Following occurrences. Do nothing. 17 | x 18 | :b 19 | } 20 | -------------------------------------------------------------------------------- /src/helper/serialize.c: -------------------------------------------------------------------------------- 1 | /** 2 | * kalu - Copyright (C) 2012-2018 Olivier Brunel 3 | * 4 | * serialize.c 5 | * Copyright (C) 2018 Olivier Brunel 6 | * 7 | * This file is part of kalu. 8 | * 9 | * kalu is free software: you can redistribute it and/or modify it under the 10 | * terms of the GNU General Public License as published by the Free Software 11 | * Foundation, either version 3 of the License, or (at your option) any later 12 | * version. 13 | * 14 | * kalu is distributed in the hope that it will be useful, but WITHOUT ANY 15 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 16 | * FOR A PARTICULAR PURPOSE. 17 | * See the GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License along with 20 | * kalu. If not, see http://www.gnu.org/licenses/ 21 | */ 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #define PROG "serialize" 32 | 33 | static void usage (int rc) 34 | { 35 | puts ("Usage: " PROG " NAME INPUT\n"); 36 | puts ("Will read INPUT and print on stdout a corresponding C file serialization\n" 37 | "with symbol NAME as const char[] and NAME_size as size_t"); 38 | _exit (rc); 39 | } 40 | 41 | static void fatal (int rc, const char *msg) 42 | { 43 | printf (PROG ": fatal error: %s: %s\n", msg, strerror (errno)); 44 | _exit (rc); 45 | } 46 | 47 | int main (int argc, const char *argv[]) 48 | { 49 | int fd; 50 | off_t len; 51 | 52 | if (argc != 3) 53 | usage (1); 54 | 55 | fd = open (argv[2], O_RDONLY | O_NONBLOCK); 56 | if (fd < 0) 57 | fatal (2, "failed to open input"); 58 | 59 | len = lseek (fd, 0, SEEK_END); 60 | if (len < 0) 61 | fatal (2, "failed to seek to end of input"); 62 | if (lseek (fd, 0, SEEK_SET) < 0) 63 | fatal (2, "failed to seek to beginning of input"); 64 | 65 | printf ("#include \nconst char %s[] = { ", argv[1]); 66 | 67 | for (;;) 68 | { 69 | char buf[len], *b = buf; 70 | ssize_t r; 71 | 72 | r = read (fd, b, len); 73 | if (r < 0) 74 | { 75 | if (errno == EINTR) 76 | continue; 77 | fatal (3, "failed to read input"); 78 | } 79 | if (r == 0) 80 | break; 81 | 82 | for ( ; r > 0; --r, ++b) 83 | printf ("%s0x%.2hhx", (b == buf) ? "" : ", ", (unsigned int) *b); 84 | 85 | len -= r; 86 | } 87 | 88 | printf (" };\nsize_t %s_size = sizeof (%s) / sizeof (*%s);", argv[1], argv[1], argv[1]); 89 | 90 | close (fd); 91 | return 0; 92 | } 93 | -------------------------------------------------------------------------------- /src/kalu-dbus/gen-interface: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # kalu - Copyright (C) 2012-2018 Olivier Brunel 4 | # 5 | # gen-interface 6 | # Copyright (C) 2012-2018 Olivier Brunel 7 | # 8 | # This file is part of kalu. 9 | # 10 | # kalu is free software: you can redistribute it and/or modify it under the 11 | # terms of the GNU General Public License as published by the Free Software 12 | # Foundation, either version 3 of the License, or (at your option) any later 13 | # version. 14 | # 15 | # kalu is distributed in the hope that it will be useful, but WITHOUT ANY 16 | # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 17 | # FOR A PARTICULAR PURPOSE. 18 | # See the GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License along with 21 | # kalu. If not, see http://www.gnu.org/licenses/ 22 | 23 | echo "/** 24 | * kalu - Copyright (C) 2012-2018 Olivier Brunel 25 | * 26 | * updater-dbus.h 27 | * Copyright (C) 2018 Olivier Brunel 28 | * 29 | * This file is part of kalu. 30 | * 31 | * kalu is free software: you can redistribute it and/or modify it under the 32 | * terms of the GNU General Public License as published by the Free Software 33 | * Foundation, either version 3 of the License, or (at your option) any later 34 | * version. 35 | * 36 | * kalu is distributed in the hope that it will be useful, but WITHOUT ANY 37 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 38 | * FOR A PARTICULAR PURPOSE. 39 | * See the GNU General Public License for more details. 40 | * 41 | * You should have received a copy of the GNU General Public License along with 42 | * kalu. If not, see http://www.gnu.org/licenses/ 43 | */ 44 | 45 | #ifndef _KALU_UPDATER_DBUS_H 46 | #define _KALU_UPDATER_DBUS_H 47 | 48 | #include \"kupdater.h\" 49 | 50 | #define DBUS_NAME \"org.jjk.kalu\" 51 | #define OBJECT_PATH \"/org/jjk/kalu/Updater\" 52 | #define INTERFACE_NAME \"org.jjk.kalu.UpdaterInterface\" 53 | 54 | " 55 | 56 | err() { 57 | [[ $line -gt 0 ]] && echo -n "Line $line: " >&2 58 | echo "$@" >&2 59 | exit 1 60 | } 61 | 62 | chk() { 63 | [[ -z "$1" ]] && err "$2" 64 | } 65 | 66 | # quick function to "parse" XML 67 | read_dom() { 68 | local IFS=\>; 69 | read -d \< K V; 70 | if [[ $? -ne 0 ]]; then 71 | return 1 72 | fi 73 | TAG=${K%% *} 74 | ATTR=${K#* } 75 | } 76 | 77 | _INTERFACE= 78 | _TYPE= 79 | _NAME= 80 | declare -A nb 81 | nb["method"]=0 82 | nb["signal"]=0 83 | declare -a methods signals args_in args_out 84 | nb_in=0 85 | nb_out=0 86 | # because with read_dom we have a "first line" before the first tag 87 | line=-1 88 | pos=0 89 | while read_dom; do 90 | (( line++ )) 91 | if [[ $pos = 0 ]]; then 92 | [[ $TAG = "node" ]] && (( pos++ )) 93 | continue 94 | elif [[ $pos = 1 ]]; then 95 | if [[ $TAG = "interface" ]]; then 96 | (( pos++ )) 97 | name= 98 | eval $ATTR 99 | chk "$name" "Interface name missing" 100 | _INTERFACE=$name 101 | fi 102 | continue 103 | elif [[ $pos -ne 2 ]]; then 104 | err "Invalid structure at pos=$pos, tag=$TAG" 105 | exit 1 106 | fi 107 | 108 | if [[ $TAG = "method" || $TAG = "signal" ]]; then 109 | name= 110 | eval $ATTR 111 | chk "$name" "Name of $TAG missing" 112 | (( nb[$TAG]++ )) 113 | if [[ $TAG = "method" ]]; then 114 | methods[${nb[$TAG]}]="_method_$name" 115 | else 116 | signals[${nb[$TAG]}]="_signal_$name" 117 | fi 118 | _TYPE=$TAG 119 | _NAME=$name 120 | ARG= 121 | elif [[ $TAG = "/method" || $TAG = "/signal" ]]; then 122 | [[ ${TAG:1} = $_TYPE ]] || err "Ending ${TAG:1} while in $_TYPE" 123 | if [[ $nb_in -gt 0 ]]; then 124 | echo "static const GDBusArgInfo * const _arg_${_NAME}_in[] = {"; 125 | for (( i=1; $i <= $nb_in; i++)); do 126 | echo " &${args_in[$i]}," 127 | done 128 | echo -e " NULL\n};" 129 | fi 130 | if [[ $nb_out -gt 0 ]]; then 131 | echo "static const GDBusArgInfo * const _arg_${_NAME}_out[] = {"; 132 | for (( i=1; $i <= $nb_out; i++)); do 133 | echo " &${args_out[$i]}," 134 | done 135 | echo -e " NULL\n};" 136 | fi 137 | if [[ $_TYPE = "method" ]]; then 138 | echo "static const GDBusMethodInfo _method_${_NAME} = {" 139 | else 140 | echo "static const GDBusSignalInfo _signal_${_NAME} = {" 141 | fi 142 | echo -e " -1,\n (gchar *) \"$_NAME\"," 143 | if [[ $nb_in = 0 && $nb_out = 0 ]]; then 144 | if [[ $_TYPE = "signal" ]]; then 145 | echo " NULL," 146 | else 147 | echo -e " NULL,\n NULL," 148 | fi 149 | else 150 | if [[ $nb_in = 0 ]]; then 151 | echo " NULL,"; 152 | else 153 | echo " (GDBusArgInfo **) (&_arg_${_NAME}_in)," 154 | fi 155 | if [[ $_TYPE = "method" ]]; then 156 | if [[ $nb_out = 0 ]]; then 157 | echo " NULL,"; 158 | else 159 | echo " (GDBusArgInfo **) (&_arg_${_NAME}_out)," 160 | fi 161 | fi 162 | fi 163 | echo -e " NULL\n};" 164 | _TYPE= 165 | _NAME= 166 | unset args_in args_out 167 | declare -a args_in args_out 168 | nb_in=0 169 | nb_out=0 170 | elif [[ $TAG = "arg" ]]; then 171 | chk "$_NAME" "Argument without parent" 172 | l=${#ATTR} 173 | [[ ${ATTR:l - 1} = "/" ]] && ATTR=${ATTR:0:l - 1} 174 | name= 175 | type= 176 | direction= 177 | eval $ATTR 178 | chk "$name" "Argument name missing" 179 | chk "$type" "Argument type missing" 180 | if [[ $_TYPE = "method" ]]; then 181 | chk "$direction" "Argument direction missing" 182 | s="_arg_${_NAME}_${direction}_${name}" 183 | else 184 | s="_arg_${_NAME}_${name}" 185 | fi 186 | echo "static const GDBusArgInfo $s = { 187 | -1, 188 | (gchar *) \"$name\", 189 | (gchar *) \"$type\", 190 | NULL 191 | };" 192 | if [[ $_TYPE = "signal" || $direction = "in" ]]; then 193 | (( nb_in++ )) 194 | args_in[nb_in]=$s 195 | else 196 | (( nb_out++ )) 197 | args_out[nb_out]=$s 198 | fi 199 | fi 200 | done < updater-dbus.xml 201 | 202 | if [[ ${nb["method"]} -gt 0 ]]; then 203 | echo "static const GDBusMethodInfo * const _methods[] = {" 204 | for name in ${methods[*]}; do 205 | echo " &$name," 206 | done 207 | echo -e " NULL\n};" 208 | fi 209 | if [[ ${nb["signal"]} -gt 0 ]]; then 210 | echo "static const GDBusSignalInfo * const _signals[] = {" 211 | for name in ${signals[*]}; do 212 | echo " &$name," 213 | done 214 | echo -e " NULL\n};" 215 | fi 216 | 217 | echo "const GDBusInterfaceInfo interface_info = { 218 | -1, 219 | (gchar *) \"$_INTERFACE\"," 220 | if [[ ${nb["method"]} -gt 0 ]]; then 221 | echo " (GDBusMethodInfo **) (&_methods)," 222 | else 223 | echo " NULL," 224 | fi 225 | if [[ ${nb["signal"]} -gt 0 ]]; then 226 | echo " (GDBusSignalInfo **) (&_signals)," 227 | else 228 | echo " NULL," 229 | fi 230 | echo -e " NULL,\n NULL\n};" 231 | 232 | echo "#endif /* _KALU_UPDATER_DBUS_H */ " 233 | -------------------------------------------------------------------------------- /src/kalu-dbus/kalu-dbus-launcher: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # we need to source /etc/profile to restore environment variables, most notably 3 | # the PATH might be required for some scripts ran during a sysupgrade (e.g. 4 | # mkinitcpio on new kernel) 5 | . /etc/profile 6 | kalu-dbus 7 | -------------------------------------------------------------------------------- /src/kalu-dbus/kupdater.h: -------------------------------------------------------------------------------- 1 | /** 2 | * kalu - Copyright (C) 2012-2018 Olivier Brunel 3 | * 4 | * kupdater.h 5 | * Copyright (C) 2012-2016 Olivier Brunel 6 | * 7 | * This file is part of kalu. 8 | * 9 | * kalu is free software: you can redistribute it and/or modify it under the 10 | * terms of the GNU General Public License as published by the Free Software 11 | * Foundation, either version 3 of the License, or (at your option) any later 12 | * version. 13 | * 14 | * kalu is distributed in the hope that it will be useful, but WITHOUT ANY 15 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 16 | * FOR A PARTICULAR PURPOSE. 17 | * See the GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License along with 20 | * kalu. If not, see http://www.gnu.org/licenses/ 21 | */ 22 | 23 | #ifndef _KALU_KUPDATER_H 24 | #define _KALU_KUPDATER_H 25 | 26 | /* keep in sync w/ kalu_alpm_syncdbs in kalu-alpm.c */ 27 | typedef enum _sync_db_results_t { 28 | SYNC_SUCCESS, 29 | SYNC_FAILURE, 30 | SYNC_NOT_NEEDED 31 | } sync_db_results_t; 32 | 33 | /* same as alpm_loglevel_t */ 34 | typedef enum _loglevel_t { 35 | LOG_ERROR = 1, 36 | LOG_WARNING = (1 << 1), 37 | LOG_DEBUG = (1 << 2), 38 | LOG_FUNCTION = (1 << 3) 39 | } loglevel_t; 40 | 41 | /* type of events for signal "Event" & "Progress" */ 42 | typedef enum _event_t { 43 | /* Event */ 44 | EVENT_CHECKING_DEPS, 45 | EVENT_RESOLVING_DEPS, 46 | EVENT_INTERCONFLICTS, 47 | EVENT_DELTA_INTEGRITY, 48 | EVENT_DELTA_PATCHES, 49 | EVENT_DELTA_PATCH_DONE, 50 | EVENT_DELTA_PATCH_FAILED, 51 | EVENT_RETRIEVING_PKGS, 52 | EVENT_RETRIEVING_PKGS_DONE, 53 | EVENT_RETRIEVING_PKGS_FAILED, 54 | EVENT_KEY_DOWNLOAD, 55 | EVENT_HOOKS_PRE, 56 | EVENT_HOOKS_POST, 57 | EVENT_TRANSACTION, 58 | /* Progress */ 59 | EVENT_INSTALLING, 60 | EVENT_REINSTALLING, 61 | EVENT_UPGRADING, 62 | EVENT_DOWNGRADING, 63 | EVENT_REMOVING, 64 | EVENT_FILE_CONFLICTS, 65 | EVENT_CHECKING_DISKSPACE, 66 | EVENT_PKG_INTEGRITY, 67 | EVENT_LOAD_PKGFILES, 68 | EVENT_KEYRING, 69 | } event_t; 70 | 71 | typedef enum _event_type_t { 72 | EVENT_TYPE_START, 73 | EVENT_TYPE_DONE 74 | } event_type_t; 75 | 76 | #endif /* _KALU_KUPDATER_H */ 77 | -------------------------------------------------------------------------------- /src/kalu-dbus/updater-dbus.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | -------------------------------------------------------------------------------- /src/kalu/aur.c: -------------------------------------------------------------------------------- 1 | /** 2 | * kalu - Copyright (C) 2012-2018 Olivier Brunel 3 | * 4 | * aur.c 5 | * Copyright (C) 2012-2016 Olivier Brunel 6 | * 7 | * This file is part of kalu. 8 | * 9 | * kalu is free software: you can redistribute it and/or modify it under the 10 | * terms of the GNU General Public License as published by the Free Software 11 | * Foundation, either version 3 of the License, or (at your option) any later 12 | * version. 13 | * 14 | * kalu is distributed in the hope that it will be useful, but WITHOUT ANY 15 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 16 | * FOR A PARTICULAR PURPOSE. 17 | * See the GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License along with 20 | * kalu. If not, see http://www.gnu.org/licenses/ 21 | */ 22 | 23 | #include 24 | 25 | /* C */ 26 | #include 27 | #include /* isalnum() */ 28 | 29 | /* glib */ 30 | #include 31 | 32 | /* alpm */ 33 | #include 34 | #include 35 | 36 | /* cjson */ 37 | #include "cJSON.h" 38 | 39 | /* kalu */ 40 | #include "kalu.h" 41 | #include "aur.h" 42 | #include "curl.h" 43 | 44 | #define MAX_URL_LENGTH 1024 45 | 46 | static void * 47 | get_pkg_from_list (const char *pkgname, alpm_list_t *pkgs, gboolean is_watched) 48 | { 49 | alpm_list_t *i; 50 | const char *name; 51 | FOR_LIST (i, pkgs) 52 | { 53 | if (is_watched) 54 | { 55 | name = ((watched_package_t *) i->data)->name; 56 | } 57 | else 58 | { 59 | name = alpm_pkg_get_name ((alpm_pkg_t *) i->data); 60 | } 61 | if (streq (pkgname, name)) 62 | { 63 | return i->data; 64 | } 65 | } 66 | return NULL; 67 | } 68 | 69 | static gint 70 | find_nf (gpointer data, gpointer _find_data) 71 | { 72 | struct { 73 | gboolean is_watched; 74 | const gchar *pkgname; 75 | } *find_data = _find_data; 76 | 77 | if (find_data->is_watched) 78 | { 79 | return strcmp (((watched_package_t *) data)->name, find_data->pkgname); 80 | } 81 | else 82 | { 83 | return strcmp (alpm_pkg_get_name ((alpm_pkg_t *) data), find_data->pkgname); 84 | } 85 | } 86 | 87 | #define add(str) do { \ 88 | len = snprintf (s, (size_t) max, "%s", str); \ 89 | max -= len; \ 90 | s += len; \ 91 | } while (0) 92 | gboolean 93 | aur_has_updates (alpm_list_t **packages, 94 | alpm_list_t **not_found, 95 | alpm_list_t *aur_pkgs, 96 | gboolean is_watched, 97 | GError **error) 98 | { 99 | alpm_list_t *urls = NULL, *i; 100 | alpm_list_t *list_nf = NULL; 101 | char buf[MAX_URL_LENGTH + 1], *s; 102 | int max, len; 103 | int len_prefix = (int) strlen (AUR_URL_PREFIX_PKG); 104 | GError *local_err = NULL; 105 | char *data; 106 | const char *pkgname, *pkgdesc, *pkgver, *oldver; 107 | cJSON *json, *results, *package; 108 | int c, j; 109 | void *pkg; 110 | kalu_package_t *kpkg; 111 | 112 | debug ((is_watched) 113 | ? "looking for Watched AUR updates" 114 | : "looking for AUR updates"); 115 | 116 | /* print start of url */ 117 | max = MAX_URL_LENGTH; 118 | s = buf; 119 | add (AUR_URL_PREFIX); 120 | 121 | FOR_LIST (i, aur_pkgs) 122 | { 123 | char *end; 124 | const char *p; 125 | 126 | if (is_watched) 127 | { 128 | pkgname = ((watched_package_t *) i->data)->name; 129 | } 130 | else 131 | { 132 | pkgname = alpm_pkg_get_name ((alpm_pkg_t *) i->data); 133 | } 134 | 135 | /* fill list of not found packages */ 136 | if (not_found || is_watched) 137 | { 138 | list_nf = alpm_list_add (list_nf, i->data); 139 | } 140 | 141 | /* make sure we can at least add the prefix */ 142 | if (len_prefix > max) 143 | { 144 | /* nope. so we store this url and start a new one */ 145 | urls = alpm_list_add (urls, strdup (buf)); 146 | max = MAX_URL_LENGTH; 147 | s = buf; 148 | add (AUR_URL_PREFIX); 149 | } 150 | 151 | /* this is where we'll end the URL, should there not be enough space */ 152 | end = s; 153 | /* add prefix */ 154 | add (AUR_URL_PREFIX_PKG); 155 | /* now we add the pkgname; one char at a time, urlencoding if needed */ 156 | for (p = pkgname; *p; ++p) 157 | { 158 | /* unreserved characters */ 159 | if (isalnum (*p) || *p == '-' || *p == '_' || *p == '.' || *p == '~') 160 | { 161 | if (max < 1) 162 | { 163 | /* add url until this pkg and start a new one */ 164 | *end = '\0'; 165 | urls = alpm_list_add (urls, strdup (buf)); 166 | max = MAX_URL_LENGTH; 167 | s = buf; 168 | add (AUR_URL_PREFIX); 169 | /* reset to start this pkgname over */ 170 | end = s; 171 | add (AUR_URL_PREFIX_PKG); 172 | p = pkgname - 1; 173 | continue; 174 | } 175 | *s++ = *p; 176 | --max; 177 | } 178 | else 179 | { 180 | const char hex[] = "0123456789ABCDEF"; 181 | 182 | if (max < 3) 183 | { 184 | /* add url until this pkg and start a new one */ 185 | *end = '\0'; 186 | urls = alpm_list_add (urls, strdup (buf)); 187 | max = MAX_URL_LENGTH; 188 | s = buf; 189 | add (AUR_URL_PREFIX); 190 | /* reset to start this pkgname over */ 191 | end = s; 192 | add (AUR_URL_PREFIX_PKG); 193 | p = pkgname - 1; 194 | continue; 195 | } 196 | /* Credit to Fred Bullback for the following */ 197 | *s++ = '%'; 198 | *s++ = hex[*p >> 4]; 199 | *s++ = hex[*p & 15]; 200 | max -= 3; 201 | } 202 | } 203 | *s = '\0'; 204 | } 205 | urls = alpm_list_add (urls, strdup (buf)); 206 | 207 | /* download */ 208 | FOR_LIST (i, urls) 209 | { 210 | data = curl_download (i->data, &local_err); 211 | if (local_err != NULL) 212 | { 213 | g_propagate_error (error, local_err); 214 | FREELIST (urls); 215 | FREE_PACKAGE_LIST (*packages); 216 | alpm_list_free (list_nf); 217 | return FALSE; 218 | } 219 | 220 | /* parse json */ 221 | debug ("parsing json"); 222 | json = cJSON_Parse (data); 223 | if (!json) 224 | { 225 | debug ("invalid json"); 226 | g_set_error (error, KALU_ERROR, 8, 227 | _("Invalid JSON response from the AUR")); 228 | FREELIST (urls); 229 | FREE_PACKAGE_LIST (*packages); 230 | alpm_list_free (list_nf); 231 | free (data); 232 | return FALSE; 233 | } 234 | results = cJSON_GetObjectItem (json, "results"); 235 | c = cJSON_GetArraySize (results); 236 | debug ("got %d results", c); 237 | for (j = 0; j < c; ++j) 238 | { 239 | package = cJSON_GetArrayItem (results, j); 240 | if (package) 241 | { 242 | /* AUR */ 243 | pkgname = cJSON_GetObjectItem (package, "Name")->valuestring; 244 | pkgdesc = cJSON_GetObjectItem (package, "Description")->valuestring; 245 | /* because desc is not required */ 246 | if (!pkgdesc) 247 | pkgdesc = ""; 248 | pkgver = cJSON_GetObjectItem (package, "Version")->valuestring; 249 | /* ALPM/watched */ 250 | pkg = get_pkg_from_list (pkgname, aur_pkgs, is_watched); 251 | if (!pkg) 252 | { 253 | debug ("package %s not found in aur_pkgs", pkgname); 254 | g_set_error (error, KALU_ERROR, 8, 255 | _("Unexpected results from the AUR [%s]"), 256 | pkgname); 257 | FREELIST (urls); 258 | FREE_PACKAGE_LIST (*packages); 259 | alpm_list_free (list_nf); 260 | free (data); 261 | cJSON_Delete (json); 262 | return FALSE; 263 | } 264 | /* remove from list of not found packages */ 265 | if (list_nf) 266 | { 267 | struct { 268 | gboolean is_watched; 269 | const gchar *pkgname; 270 | } find_data = { is_watched, pkgname }; 271 | list_nf = alpm_list_remove (list_nf, &find_data, 272 | (alpm_list_fn_cmp) find_nf, NULL); 273 | } 274 | if (is_watched) 275 | { 276 | oldver = ((watched_package_t *) pkg)->version; 277 | } 278 | else 279 | { 280 | oldver = alpm_pkg_get_version ((alpm_pkg_t *) pkg); 281 | } 282 | /* is AUR newer? */ 283 | if (alpm_pkg_vercmp (pkgver, oldver) == 1) 284 | { 285 | debug ("%s %s -> %s", pkgname, oldver, pkgver); 286 | kpkg = new0 (kalu_package_t, 1); 287 | kpkg->name = strdup (pkgname); 288 | kpkg->desc = strdup (pkgdesc); 289 | kpkg->old_version = strdup (oldver); 290 | kpkg->new_version = strdup (pkgver); 291 | *packages = alpm_list_add (*packages, kpkg); 292 | } 293 | } 294 | } 295 | cJSON_Delete (json); 296 | free (data); 297 | } 298 | FREELIST (urls); 299 | 300 | /* turn not_found into a list of kalu_package_t as it should be, or add them 301 | * to packages (if not_found is NULL, i.e. is_watched is TRUE) */ 302 | if (list_nf) 303 | { 304 | FOR_LIST (i, list_nf) 305 | { 306 | kpkg = new0 (kalu_package_t, 1); 307 | 308 | if (is_watched) 309 | { 310 | watched_package_t *wp = i->data; 311 | 312 | kpkg->name = strdup (wp->name); 313 | kpkg->desc = strdup (_("")); 314 | kpkg->old_version = strdup (wp->version); 315 | kpkg->new_version = strdup ("-"); 316 | } 317 | else 318 | { 319 | alpm_pkg_t *p = i->data; 320 | 321 | kpkg->name = strdup (alpm_pkg_get_name (p)); 322 | kpkg->desc = strdup (alpm_pkg_get_desc (p)); 323 | kpkg->old_version = strdup (alpm_pkg_get_version (p)); 324 | } 325 | 326 | if (not_found) 327 | { 328 | debug ("adding to not found: package %s", kpkg->name); 329 | *not_found = alpm_list_add (*not_found, kpkg); 330 | } 331 | else 332 | { 333 | debug ("not found: %s", kpkg->name); 334 | *packages = alpm_list_add (*packages, kpkg); 335 | } 336 | } 337 | alpm_list_free (list_nf); 338 | } 339 | 340 | return (*packages != NULL); 341 | } 342 | #undef add 343 | -------------------------------------------------------------------------------- /src/kalu/aur.h: -------------------------------------------------------------------------------- 1 | /** 2 | * kalu - Copyright (C) 2012-2018 Olivier Brunel 3 | * 4 | * aur.h 5 | * Copyright (C) 2012-2014 Olivier Brunel 6 | * 7 | * This file is part of kalu. 8 | * 9 | * kalu is free software: you can redistribute it and/or modify it under the 10 | * terms of the GNU General Public License as published by the Free Software 11 | * Foundation, either version 3 of the License, or (at your option) any later 12 | * version. 13 | * 14 | * kalu is distributed in the hope that it will be useful, but WITHOUT ANY 15 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 16 | * FOR A PARTICULAR PURPOSE. 17 | * See the GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License along with 20 | * kalu. If not, see http://www.gnu.org/licenses/ 21 | */ 22 | 23 | #ifndef _KALU_AUR_H 24 | #define _KALU_AUR_H 25 | 26 | gboolean 27 | aur_has_updates (alpm_list_t **packages, 28 | alpm_list_t **not_found, 29 | alpm_list_t *aur_pkgs, 30 | gboolean is_watched, 31 | GError **error); 32 | 33 | #endif /* _KALU_AUR_H */ 34 | -------------------------------------------------------------------------------- /src/kalu/cJSON.README: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2009 Dave Gamble 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | */ 22 | 23 | Welcome to cJSON. 24 | 25 | cJSON aims to be the dumbest possible parser that you can get your job done with. 26 | It's a single file of C, and a single header file. 27 | 28 | JSON is described best here: http://www.json.org/ 29 | It's like XML, but fat-free. You use it to move data around, store things, or just 30 | generally represent your program's state. 31 | 32 | 33 | First up, how do I build? 34 | Add cJSON.c to your project, and put cJSON.h somewhere in the header search path. 35 | For example, to build the test app: 36 | 37 | gcc cJSON.c test.c -o test -lm 38 | ./test 39 | 40 | 41 | As a library, cJSON exists to take away as much legwork as it can, but not get in your way. 42 | As a point of pragmatism (i.e. ignoring the truth), I'm going to say that you can use it 43 | in one of two modes: Auto and Manual. Let's have a quick run-through. 44 | 45 | 46 | I lifted some JSON from this page: http://www.json.org/fatfree.html 47 | That page inspired me to write cJSON, which is a parser that tries to share the same 48 | philosophy as JSON itself. Simple, dumb, out of the way. 49 | 50 | Some JSON: 51 | { 52 | "name": "Jack (\"Bee\") Nimble", 53 | "format": { 54 | "type": "rect", 55 | "width": 1920, 56 | "height": 1080, 57 | "interlace": false, 58 | "frame rate": 24 59 | } 60 | } 61 | 62 | Assume that you got this from a file, a webserver, or magic JSON elves, whatever, 63 | you have a char * to it. Everything is a cJSON struct. 64 | Get it parsed: 65 | cJSON *root = cJSON_Parse(my_json_string); 66 | 67 | This is an object. We're in C. We don't have objects. But we do have structs. 68 | What's the framerate? 69 | 70 | cJSON *format = cJSON_GetObjectItem(root,"format"); 71 | int framerate = cJSON_GetObjectItem(format,"frame rate")->valueint; 72 | 73 | 74 | Want to change the framerate? 75 | cJSON_GetObjectItem(format,"frame rate")->valueint=25; 76 | 77 | Back to disk? 78 | char *rendered=cJSON_Print(root); 79 | 80 | Finished? Delete the root (this takes care of everything else). 81 | cJSON_Delete(root); 82 | 83 | That's AUTO mode. If you're going to use Auto mode, you really ought to check pointers 84 | before you dereference them. If you want to see how you'd build this struct in code? 85 | cJSON *root,*fmt; 86 | root=cJSON_CreateObject(); 87 | cJSON_AddItemToObject(root, "name", cJSON_CreateString("Jack (\"Bee\") Nimble")); 88 | cJSON_AddItemToObject(root, "format", fmt=cJSON_CreateObject()); 89 | cJSON_AddStringToObject(fmt,"type", "rect"); 90 | cJSON_AddNumberToObject(fmt,"width", 1920); 91 | cJSON_AddNumberToObject(fmt,"height", 1080); 92 | cJSON_AddFalseToObject (fmt,"interlace"); 93 | cJSON_AddNumberToObject(fmt,"frame rate", 24); 94 | 95 | Hopefully we can agree that's not a lot of code? There's no overhead, no unnecessary setup. 96 | Look at test.c for a bunch of nice examples, mostly all ripped off the json.org site, and 97 | a few from elsewhere. 98 | 99 | What about manual mode? First up you need some detail. 100 | Let's cover how the cJSON objects represent the JSON data. 101 | cJSON doesn't distinguish arrays from objects in handling; just type. 102 | Each cJSON has, potentially, a child, siblings, value, a name. 103 | 104 | The root object has: Object Type and a Child 105 | The Child has name "name", with value "Jack ("Bee") Nimble", and a sibling: 106 | Sibling has type Object, name "format", and a child. 107 | That child has type String, name "type", value "rect", and a sibling: 108 | Sibling has type Number, name "width", value 1920, and a sibling: 109 | Sibling has type Number, name "height", value 1080, and a sibling: 110 | Sibling hs type False, name "interlace", and a sibling: 111 | Sibling has type Number, name "frame rate", value 24 112 | 113 | Here's the structure: 114 | typedef struct cJSON { 115 | struct cJSON *next,*prev; 116 | struct cJSON *child; 117 | 118 | int type; 119 | 120 | char *valuestring; 121 | int valueint; 122 | double valuedouble; 123 | 124 | char *string; 125 | } cJSON; 126 | 127 | By default all values are 0 unless set by virtue of being meaningful. 128 | 129 | next/prev is a doubly linked list of siblings. next takes you to your sibling, 130 | prev takes you back from your sibling to you. 131 | Only objects and arrays have a "child", and it's the head of the doubly linked list. 132 | A "child" entry will have prev==0, but next potentially points on. The last sibling has next=0. 133 | The type expresses Null/True/False/Number/String/Array/Object, all of which are #defined in 134 | cJSON.h 135 | 136 | A Number has valueint and valuedouble. If you're expecting an int, read valueint, if not read 137 | valuedouble. 138 | 139 | Any entry which is in the linked list which is the child of an object will have a "string" 140 | which is the "name" of the entry. When I said "name" in the above example, that's "string". 141 | "string" is the JSON name for the 'variable name' if you will. 142 | 143 | Now you can trivially walk the lists, recursively, and parse as you please. 144 | You can invoke cJSON_Parse to get cJSON to parse for you, and then you can take 145 | the root object, and traverse the structure (which is, formally, an N-tree), 146 | and tokenise as you please. If you wanted to build a callback style parser, this is how 147 | you'd do it (just an example, since these things are very specific): 148 | 149 | void parse_and_callback(cJSON *item,const char *prefix) 150 | { 151 | while (item) 152 | { 153 | char *newprefix=malloc(strlen(prefix)+strlen(item->name)+2); 154 | sprintf(newprefix,"%s/%s",prefix,item->name); 155 | int dorecurse=callback(newprefix, item->type, item); 156 | if (item->child && dorecurse) parse_and_callback(item->child,newprefix); 157 | item=item->next; 158 | free(newprefix); 159 | } 160 | } 161 | 162 | The prefix process will build you a separated list, to simplify your callback handling. 163 | The 'dorecurse' flag would let the callback decide to handle sub-arrays on it's own, or 164 | let you invoke it per-item. For the item above, your callback might look like this: 165 | 166 | int callback(const char *name,int type,cJSON *item) 167 | { 168 | if (!strcmp(name,"name")) { /* populate name */ } 169 | else if (!strcmp(name,"format/type") { /* handle "rect" */ } 170 | else if (!strcmp(name,"format/width") { /* 800 */ } 171 | else if (!strcmp(name,"format/height") { /* 600 */ } 172 | else if (!strcmp(name,"format/interlace") { /* false */ } 173 | else if (!strcmp(name,"format/frame rate") { /* 24 */ } 174 | return 1; 175 | } 176 | 177 | Alternatively, you might like to parse iteratively. 178 | You'd use: 179 | 180 | void parse_object(cJSON *item) 181 | { 182 | int i; for (i=0;ichild; 194 | while (subitem) 195 | { 196 | // handle subitem 197 | if (subitem->child) parse_object(subitem->child); 198 | 199 | subitem=subitem->next; 200 | } 201 | } 202 | 203 | Of course, this should look familiar, since this is just a stripped-down version 204 | of the callback-parser. 205 | 206 | This should cover most uses you'll find for parsing. The rest should be possible 207 | to infer.. and if in doubt, read the source! There's not a lot of it! ;) 208 | 209 | 210 | In terms of constructing JSON data, the example code above is the right way to do it. 211 | You can, of course, hand your sub-objects to other functions to populate. 212 | Also, if you find a use for it, you can manually build the objects. 213 | For instance, suppose you wanted to build an array of objects? 214 | 215 | cJSON *objects[24]; 216 | 217 | cJSON *Create_array_of_anything(cJSON **items,int num) 218 | { 219 | int i;cJSON *prev, *root=cJSON_CreateArray(); 220 | for (i=0;i<24;i++) 221 | { 222 | if (!i) root->child=objects[i]; 223 | else prev->next=objects[i], objects[i]->prev=prev; 224 | prev=objects[i]; 225 | } 226 | return root; 227 | } 228 | 229 | and simply: Create_array_of_anything(objects,24); 230 | 231 | cJSON doesn't make any assumptions about what order you create things in. 232 | You can attach the objects, as above, and later add children to each 233 | of those objects. 234 | 235 | As soon as you call cJSON_Print, it renders the structure to text. 236 | 237 | 238 | 239 | The test.c code shows how to handle a bunch of typical cases. If you uncomment 240 | the code, it'll load, parse and print a bunch of test files, also from json.org, 241 | which are more complex than I'd care to try and stash into a const char array[]. 242 | 243 | 244 | Enjoy cJSON! 245 | 246 | 247 | - Dave Gamble, Aug 2009 248 | -------------------------------------------------------------------------------- /src/kalu/cJSON.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2009 Dave Gamble 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | */ 22 | 23 | #ifndef cJSON__h 24 | #define cJSON__h 25 | 26 | #ifdef __cplusplus 27 | extern "C" 28 | { 29 | #endif 30 | 31 | /* cJSON Types: */ 32 | #define cJSON_False 0 33 | #define cJSON_True 1 34 | #define cJSON_NULL 2 35 | #define cJSON_Number 3 36 | #define cJSON_String 4 37 | #define cJSON_Array 5 38 | #define cJSON_Object 6 39 | 40 | #define cJSON_IsReference 256 41 | 42 | /* The cJSON structure: */ 43 | typedef struct cJSON { 44 | struct cJSON *next,*prev; /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */ 45 | struct cJSON *child; /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */ 46 | 47 | int type; /* The type of the item, as above. */ 48 | 49 | char *valuestring; /* The item's string, if type==cJSON_String */ 50 | int valueint; /* The item's number, if type==cJSON_Number */ 51 | double valuedouble; /* The item's number, if type==cJSON_Number */ 52 | 53 | char *string; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */ 54 | } cJSON; 55 | 56 | typedef struct cJSON_Hooks { 57 | void *(*malloc_fn)(size_t sz); 58 | void (*free_fn)(void *ptr); 59 | } cJSON_Hooks; 60 | 61 | /* Supply malloc, realloc and free functions to cJSON */ 62 | extern void cJSON_InitHooks(cJSON_Hooks* hooks); 63 | 64 | 65 | /* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. */ 66 | extern cJSON *cJSON_Parse(const char *value); 67 | /* Render a cJSON entity to text for transfer/storage. Free the char* when finished. */ 68 | extern char *cJSON_Print(cJSON *item); 69 | /* Render a cJSON entity to text for transfer/storage without any formatting. Free the char* when finished. */ 70 | extern char *cJSON_PrintUnformatted(cJSON *item); 71 | /* Delete a cJSON entity and all subentities. */ 72 | extern void cJSON_Delete(cJSON *c); 73 | 74 | /* Returns the number of items in an array (or object). */ 75 | extern int cJSON_GetArraySize(cJSON *array); 76 | /* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */ 77 | extern cJSON *cJSON_GetArrayItem(cJSON *array,int item); 78 | /* Get item "string" from object. Case insensitive. */ 79 | extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string); 80 | 81 | /* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */ 82 | extern const char *cJSON_GetErrorPtr(void); 83 | 84 | /* These calls create a cJSON item of the appropriate type. */ 85 | extern cJSON *cJSON_CreateNull(void); 86 | extern cJSON *cJSON_CreateTrue(void); 87 | extern cJSON *cJSON_CreateFalse(void); 88 | extern cJSON *cJSON_CreateBool(int b); 89 | extern cJSON *cJSON_CreateNumber(double num); 90 | extern cJSON *cJSON_CreateString(const char *string); 91 | extern cJSON *cJSON_CreateArray(void); 92 | extern cJSON *cJSON_CreateObject(void); 93 | 94 | /* These utilities create an Array of count items. */ 95 | extern cJSON *cJSON_CreateIntArray(int *numbers,int count); 96 | extern cJSON *cJSON_CreateFloatArray(float *numbers,int count); 97 | extern cJSON *cJSON_CreateDoubleArray(double *numbers,int count); 98 | extern cJSON *cJSON_CreateStringArray(const char **strings,int count); 99 | 100 | /* Append item to the specified array/object. */ 101 | extern void cJSON_AddItemToArray(cJSON *array, cJSON *item); 102 | extern void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item); 103 | /* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */ 104 | extern void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item); 105 | extern void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item); 106 | 107 | /* Remove/Detatch items from Arrays/Objects. */ 108 | extern cJSON *cJSON_DetachItemFromArray(cJSON *array,int which); 109 | extern void cJSON_DeleteItemFromArray(cJSON *array,int which); 110 | extern cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string); 111 | extern void cJSON_DeleteItemFromObject(cJSON *object,const char *string); 112 | 113 | /* Update array items. */ 114 | extern void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem); 115 | extern void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem); 116 | 117 | #define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull()) 118 | #define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue()) 119 | #define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse()) 120 | #define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n)) 121 | #define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s)) 122 | 123 | #ifdef __cplusplus 124 | } 125 | #endif 126 | 127 | #endif 128 | -------------------------------------------------------------------------------- /src/kalu/closures: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | glib-genmarshal --header closures.def >closures.h.new 4 | glib-genmarshal --body closures.def >closures.c.new 5 | 6 | -------------------------------------------------------------------------------- /src/kalu/closures.def: -------------------------------------------------------------------------------- 1 | VOID:STRING,UINT,UINT 2 | VOID:INT,STRING 3 | BOOLEAN:STRING 4 | BOOLEAN:STRING,STRING,STRING,STRING 5 | BOOLEAN:STRING,STRING,STRING 6 | BOOLEAN:POINTER 7 | INT:STRING,POINTER 8 | BOOLEAN:STRING,STRING 9 | VOID:STRING,STRING,POINTER 10 | VOID:STRING,STRING 11 | VOID:STRING,STRING,STRING,POINTER 12 | VOID:INT,STRING,INT,UINT,UINT 13 | VOID:INT,STRING,STRING,STRING,STRING 14 | VOID:STRING,STRING,STRING 15 | VOID:UINT,INT,INT,STRING,STRING 16 | 17 | -------------------------------------------------------------------------------- /src/kalu/closures.h: -------------------------------------------------------------------------------- 1 | /** 2 | * kalu - Copyright (C) 2012-2016 Olivier Brunel 3 | * 4 | * closures.h 5 | * Copyright (C) 2012-2016 Olivier Brunel 6 | * 7 | * This file is part of kalu. 8 | * 9 | * kalu is free software: you can redistribute it and/or modify it under the 10 | * terms of the GNU General Public License as published by the Free Software 11 | * Foundation, either version 3 of the License, or (at your option) any later 12 | * version. 13 | * 14 | * kalu is distributed in the hope that it will be useful, but WITHOUT ANY 15 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 16 | * FOR A PARTICULAR PURPOSE. 17 | * See the GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License along with 20 | * kalu. If not, see http://www.gnu.org/licenses/ 21 | */ 22 | 23 | #ifndef __g_cclosure_user_marshal_MARSHAL_H__ 24 | #define __g_cclosure_user_marshal_MARSHAL_H__ 25 | 26 | #include 27 | 28 | G_BEGIN_DECLS 29 | 30 | /* VOID:STRING,UINT,UINT (closures.def:1) */ 31 | extern void g_cclosure_user_marshal_VOID__STRING_UINT_UINT (GClosure *closure, 32 | GValue *return_value, 33 | guint n_param_values, 34 | const GValue *param_values, 35 | gpointer invocation_hint, 36 | gpointer marshal_data); 37 | 38 | /* VOID:INT,STRING (closures.def:2) */ 39 | extern void g_cclosure_user_marshal_VOID__INT_STRING (GClosure *closure, 40 | GValue *return_value, 41 | guint n_param_values, 42 | const GValue *param_values, 43 | gpointer invocation_hint, 44 | gpointer marshal_data); 45 | 46 | /* BOOLEAN:STRING (closures.def:3) */ 47 | extern void g_cclosure_user_marshal_BOOLEAN__STRING (GClosure *closure, 48 | GValue *return_value, 49 | guint n_param_values, 50 | const GValue *param_values, 51 | gpointer invocation_hint, 52 | gpointer marshal_data); 53 | 54 | /* BOOLEAN:STRING,STRING,STRING,STRING (closures.def:4) */ 55 | extern void g_cclosure_user_marshal_BOOLEAN__STRING_STRING_STRING_STRING (GClosure *closure, 56 | GValue *return_value, 57 | guint n_param_values, 58 | const GValue *param_values, 59 | gpointer invocation_hint, 60 | gpointer marshal_data); 61 | 62 | /* BOOLEAN:STRING,STRING,STRING (closures.def:5) */ 63 | extern void g_cclosure_user_marshal_BOOLEAN__STRING_STRING_STRING (GClosure *closure, 64 | GValue *return_value, 65 | guint n_param_values, 66 | const GValue *param_values, 67 | gpointer invocation_hint, 68 | gpointer marshal_data); 69 | 70 | /* BOOLEAN:POINTER (closures.def:6) */ 71 | extern void g_cclosure_user_marshal_BOOLEAN__POINTER (GClosure *closure, 72 | GValue *return_value, 73 | guint n_param_values, 74 | const GValue *param_values, 75 | gpointer invocation_hint, 76 | gpointer marshal_data); 77 | 78 | /* INT:STRING,POINTER (closures.def:7) */ 79 | extern void g_cclosure_user_marshal_INT__STRING_POINTER (GClosure *closure, 80 | GValue *return_value, 81 | guint n_param_values, 82 | const GValue *param_values, 83 | gpointer invocation_hint, 84 | gpointer marshal_data); 85 | 86 | /* BOOLEAN:STRING,STRING (closures.def:8) */ 87 | extern void g_cclosure_user_marshal_BOOLEAN__STRING_STRING (GClosure *closure, 88 | GValue *return_value, 89 | guint n_param_values, 90 | const GValue *param_values, 91 | gpointer invocation_hint, 92 | gpointer marshal_data); 93 | 94 | /* VOID:STRING,STRING,POINTER (closures.def:9) */ 95 | extern void g_cclosure_user_marshal_VOID__STRING_STRING_POINTER (GClosure *closure, 96 | GValue *return_value, 97 | guint n_param_values, 98 | const GValue *param_values, 99 | gpointer invocation_hint, 100 | gpointer marshal_data); 101 | 102 | /* VOID:STRING,STRING (closures.def:10) */ 103 | extern void g_cclosure_user_marshal_VOID__STRING_STRING (GClosure *closure, 104 | GValue *return_value, 105 | guint n_param_values, 106 | const GValue *param_values, 107 | gpointer invocation_hint, 108 | gpointer marshal_data); 109 | 110 | /* VOID:STRING,STRING,STRING,POINTER (closures.def:11) */ 111 | extern void g_cclosure_user_marshal_VOID__STRING_STRING_STRING_POINTER (GClosure *closure, 112 | GValue *return_value, 113 | guint n_param_values, 114 | const GValue *param_values, 115 | gpointer invocation_hint, 116 | gpointer marshal_data); 117 | 118 | /* VOID:INT,STRING,INT,UINT,UINT (closures.def:12) */ 119 | extern void g_cclosure_user_marshal_VOID__INT_STRING_INT_UINT_UINT (GClosure *closure, 120 | GValue *return_value, 121 | guint n_param_values, 122 | const GValue *param_values, 123 | gpointer invocation_hint, 124 | gpointer marshal_data); 125 | 126 | /* VOID:INT,STRING,STRING,STRING,STRING (closures.def:13) */ 127 | extern void g_cclosure_user_marshal_VOID__INT_STRING_STRING_STRING_STRING (GClosure *closure, 128 | GValue *return_value, 129 | guint n_param_values, 130 | const GValue *param_values, 131 | gpointer invocation_hint, 132 | gpointer marshal_data); 133 | 134 | /* VOID:STRING,STRING,STRING (closures.def:14) */ 135 | extern void g_cclosure_user_marshal_VOID__STRING_STRING_STRING (GClosure *closure, 136 | GValue *return_value, 137 | guint n_param_values, 138 | const GValue *param_values, 139 | gpointer invocation_hint, 140 | gpointer marshal_data); 141 | 142 | /* VOID:UINT,INT,INT,STRING,STRING (closures.def:15) */ 143 | extern void g_cclosure_user_marshal_VOID__UINT_INT_INT_STRING_STRING (GClosure *closure, 144 | GValue *return_value, 145 | guint n_param_values, 146 | const GValue *param_values, 147 | gpointer invocation_hint, 148 | gpointer marshal_data); 149 | 150 | G_END_DECLS 151 | 152 | #endif /* __g_cclosure_user_marshal_MARSHAL_H__ */ 153 | 154 | -------------------------------------------------------------------------------- /src/kalu/conf.h: -------------------------------------------------------------------------------- 1 | /** 2 | * kalu - Copyright (C) 2012-2018 Olivier Brunel 3 | * 4 | * conf.h 5 | * Copyright (C) 2012-2016 Olivier Brunel 6 | * 7 | * This file is part of kalu. 8 | * 9 | * kalu is free software: you can redistribute it and/or modify it under the 10 | * terms of the GNU General Public License as published by the Free Software 11 | * Foundation, either version 3 of the License, or (at your option) any later 12 | * version. 13 | * 14 | * kalu is distributed in the hope that it will be useful, but WITHOUT ANY 15 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 16 | * FOR A PARTICULAR PURPOSE. 17 | * See the GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License along with 20 | * kalu. If not, see http://www.gnu.org/licenses/ 21 | */ 22 | 23 | #ifndef _KALU_CONFIG_H 24 | #define _KALU_CONFIG_H 25 | 26 | /* glib */ 27 | #include 28 | 29 | /* alpm */ 30 | #include 31 | #include 32 | 33 | /* type of conf file to parse */ 34 | typedef enum _conf_file_t { 35 | CONF_FILE_KALU, 36 | CONF_FILE_WATCHED, 37 | CONF_FILE_WATCHED_AUR, 38 | CONF_FILE_NEWS 39 | } conf_file_t; 40 | 41 | /* database definition from parsing conf */ 42 | typedef struct _database_t { 43 | char *name; 44 | alpm_siglevel_t siglevel; 45 | alpm_list_t *siglevel_def; /* for internal processing/parsing */ 46 | alpm_list_t *servers; 47 | } database_t; 48 | 49 | /* config data loaded from parsing pacman.conf */ 50 | typedef struct _pacman_config_t { 51 | /* alpm */ 52 | char *rootdir; 53 | char *dbpath; 54 | char *logfile; 55 | char *gpgdir; 56 | alpm_list_t *hookdirs; 57 | alpm_list_t *cachedirs; 58 | alpm_siglevel_t siglevel; 59 | char *arch; 60 | int checkspace; 61 | int usesyslog; 62 | double usedelta; 63 | alpm_list_t *ignorepkgs; 64 | alpm_list_t *ignoregroups; 65 | alpm_list_t *noupgrades; 66 | alpm_list_t *noextracts; 67 | 68 | /* non-alpm */ 69 | alpm_list_t *syncfirst; 70 | unsigned short verbosepkglists; 71 | 72 | /* dbs/repos */ 73 | alpm_list_t *databases; 74 | } pacman_config_t; 75 | 76 | gboolean 77 | parse_pacman_conf (const char *file, 78 | char **name, 79 | int is_options, 80 | int depth, 81 | pacman_config_t **pac_conf, 82 | GError **error); 83 | 84 | void 85 | free_pacman_config (pacman_config_t *pac_conf); 86 | 87 | gboolean 88 | parse_config_file (const char *file, 89 | conf_file_t conf_file, 90 | GError **error); 91 | 92 | 93 | #endif /* _KALU_CONFIG_H */ 94 | -------------------------------------------------------------------------------- /src/kalu/curl.c: -------------------------------------------------------------------------------- 1 | /** 2 | * kalu - Copyright (C) 2012-2018 Olivier Brunel 3 | * 4 | * curl.c 5 | * Copyright (C) 2012-2014 Olivier Brunel 6 | * 7 | * This file is part of kalu. 8 | * 9 | * kalu is free software: you can redistribute it and/or modify it under the 10 | * terms of the GNU General Public License as published by the Free Software 11 | * Foundation, either version 3 of the License, or (at your option) any later 12 | * version. 13 | * 14 | * kalu is distributed in the hope that it will be useful, but WITHOUT ANY 15 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 16 | * FOR A PARTICULAR PURPOSE. 17 | * See the GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License along with 20 | * kalu. If not, see http://www.gnu.org/licenses/ 21 | */ 22 | 23 | #include 24 | 25 | /* C */ 26 | #include 27 | 28 | /* curl */ 29 | #include 30 | 31 | /* kalu */ 32 | #include "kalu.h" 33 | #include "curl.h" 34 | 35 | /* struct to hold data downloaded via curl */ 36 | typedef struct _string_t { 37 | char *content; 38 | size_t len; 39 | size_t alloc; 40 | } string_t; 41 | 42 | static size_t 43 | curl_write (void *content, size_t size, size_t nmemb, string_t *data) 44 | { 45 | size_t total = size * nmemb; 46 | 47 | /* alloc memory if needed */ 48 | if (data->len + total >= data->alloc) 49 | { 50 | data->alloc += total + 1024; 51 | data->content = renew (char, data->alloc, data->content); 52 | } 53 | 54 | /* copy data */ 55 | memcpy (&(data->content[data->len]), content, total); 56 | data->len += total; 57 | 58 | return total; 59 | } 60 | 61 | char * 62 | curl_download (const char *url, GError **error) 63 | { 64 | CURL *curl; 65 | string_t data; 66 | char errmsg[CURL_ERROR_SIZE]; 67 | 68 | debug ("downloading %s", url); 69 | zero (data); 70 | 71 | curl = curl_easy_init(); 72 | if (!curl) 73 | { 74 | g_set_error (error, KALU_ERROR, 1, _("Unable to init cURL\n")); 75 | return NULL; 76 | } 77 | 78 | curl_easy_setopt (curl, CURLOPT_USERAGENT, PACKAGE_NAME "/" PACKAGE_VERSION); 79 | curl_easy_setopt (curl, CURLOPT_URL, url); 80 | curl_easy_setopt (curl, CURLOPT_FOLLOWLOCATION, 1); 81 | curl_easy_setopt (curl, CURLOPT_NOPROGRESS, 1); 82 | curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, (curl_write_callback) curl_write); 83 | curl_easy_setopt (curl, CURLOPT_WRITEDATA, (void *) &data); 84 | curl_easy_setopt (curl, CURLOPT_ERRORBUFFER, errmsg); 85 | if (config->use_ip == IPv4) 86 | { 87 | debug ("set curl to IPv4"); 88 | curl_easy_setopt (curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); 89 | } 90 | else if (config->use_ip == IPv6) 91 | { 92 | debug ("set curl to IPv6"); 93 | curl_easy_setopt (curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V6); 94 | } 95 | 96 | if (curl_easy_perform (curl) != 0) 97 | { 98 | curl_easy_cleanup (curl); 99 | if (data.content != NULL) 100 | { 101 | free (data.content); 102 | } 103 | g_set_error (error, KALU_ERROR, 1, "%s", errmsg); 104 | return NULL; 105 | } 106 | curl_easy_cleanup (curl); 107 | debug ("downloaded %d bytes", data.len); 108 | 109 | /* content is not NULL-terminated yet */ 110 | data.content[data.len] = '\0'; 111 | 112 | return data.content; 113 | } 114 | -------------------------------------------------------------------------------- /src/kalu/curl.h: -------------------------------------------------------------------------------- 1 | /** 2 | * kalu - Copyright (C) 2012-2018 Olivier Brunel 3 | * 4 | * curl.h 5 | * Copyright (C) 2012-2014 Olivier Brunel 6 | * 7 | * This file is part of kalu. 8 | * 9 | * kalu is free software: you can redistribute it and/or modify it under the 10 | * terms of the GNU General Public License as published by the Free Software 11 | * Foundation, either version 3 of the License, or (at your option) any later 12 | * version. 13 | * 14 | * kalu is distributed in the hope that it will be useful, but WITHOUT ANY 15 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 16 | * FOR A PARTICULAR PURPOSE. 17 | * See the GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License along with 20 | * kalu. If not, see http://www.gnu.org/licenses/ 21 | */ 22 | 23 | #ifndef _KALU_CURL_H 24 | #define _KALU_CURL_H 25 | 26 | /* glib */ 27 | #include 28 | 29 | char * 30 | curl_download (const char *url, GError **error); 31 | 32 | #endif /* _KALU_CURL_H */ 33 | -------------------------------------------------------------------------------- /src/kalu/gui.h: -------------------------------------------------------------------------------- 1 | /** 2 | * kalu - Copyright (C) 2012-2018 Olivier Brunel 3 | * 4 | * gui.h 5 | * Copyright (C) 2012-2016 Olivier Brunel 6 | * 7 | * This file is part of kalu. 8 | * 9 | * kalu is free software: you can redistribute it and/or modify it under the 10 | * terms of the GNU General Public License as published by the Free Software 11 | * Foundation, either version 3 of the License, or (at your option) any later 12 | * version. 13 | * 14 | * kalu is distributed in the hope that it will be useful, but WITHOUT ANY 15 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 16 | * FOR A PARTICULAR PURPOSE. 17 | * See the GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License along with 20 | * kalu. If not, see http://www.gnu.org/licenses/ 21 | */ 22 | 23 | #ifndef _GUI_H 24 | #define _GUI_H 25 | 26 | /* C */ 27 | #include 28 | 29 | /* alpm */ 30 | #include 31 | 32 | /* gtk */ 33 | #include 34 | 35 | /* notify */ 36 | #include 37 | 38 | /* statusnotifier */ 39 | #ifdef ENABLE_STATUS_NOTIFIER 40 | #include 41 | #endif 42 | 43 | #define FREE_NOTIFS_LIST(p) \ 44 | do \ 45 | { \ 46 | alpm_list_free_inner (p, (alpm_list_fn_free) free_notif); \ 47 | alpm_list_free (p); \ 48 | p = NULL; \ 49 | } while(0) 50 | 51 | 52 | void free_notif (notif_t *notif); 53 | void show_notif (notif_t *notif); 54 | 55 | gboolean show_error_cmdline (gchar *arg[]); 56 | 57 | void action_upgrade (NotifyNotification *notification, 58 | const char *action, 59 | gchar *_cmdline); 60 | void action_watched (NotifyNotification *notification, 61 | char *action, 62 | notif_t *notif); 63 | void action_watched_aur (NotifyNotification *notification, 64 | char *action, 65 | notif_t *notif); 66 | void action_news (NotifyNotification *notification, 67 | char *action, 68 | notif_t *notif); 69 | 70 | void notification_closed_cb (NotifyNotification *notification, gpointer data); 71 | 72 | gboolean is_pacman_conflicting (alpm_list_t *packages); 73 | 74 | void kalu_check (gboolean is_auto); 75 | gboolean kalu_auto_check (void); 76 | 77 | #ifdef ENABLE_STATUS_NOTIFIER 78 | void sn_cb (gpointer data); 79 | void sn_context_menu_cb (StatusNotifier *_sn, gint x, gint y, gpointer data); 80 | #endif 81 | void icon_popup_cb (GtkStatusIcon *_icon, guint button, guint activate_time, 82 | gpointer data); 83 | 84 | void add_open_window (gpointer window); 85 | void remove_open_window (gpointer window); 86 | 87 | gboolean icon_press_cb (GtkStatusIcon *icon, GdkEventButton *event, 88 | gpointer data); 89 | 90 | gboolean icon_query_tooltip_cb (GtkWidget *icon, gint x, gint y, 91 | gboolean keyboard_mode, GtkTooltip *tooltip, gpointer data); 92 | 93 | void process_fifo_command (const gchar *command); 94 | 95 | void set_kalpm_nb (check_t type, gint nb, gboolean update_icon); 96 | GString **get_kalpm_synced_dbs (void); 97 | void reset_kalpm_synced_dbs (void); 98 | void set_kalpm_busy (gboolean busy); 99 | void reset_timeout (void); 100 | gboolean skip_next_timeout (gpointer no_checks); 101 | gboolean reload_watched (gboolean is_aur, GError **error); 102 | 103 | #endif /* _GUI_H */ 104 | -------------------------------------------------------------------------------- /src/kalu/imagemenuitem.h: -------------------------------------------------------------------------------- 1 | /** 2 | * kalu - Copyright (C) 2012-2018 Olivier Brunel 3 | * 4 | * imagemenuitem.h 5 | * Copyright (C) 2014 Olivier Brunel 6 | * 7 | * This file is part of kalu. 8 | * 9 | * kalu is free software: you can redistribute it and/or modify it under the 10 | * terms of the GNU General Public License as published by the Free Software 11 | * Foundation, either version 3 of the License, or (at your option) any later 12 | * version. 13 | * 14 | * kalu is distributed in the hope that it will be useful, but WITHOUT ANY 15 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 16 | * FOR A PARTICULAR PURPOSE. 17 | * See the GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License along with 20 | * kalu. If not, see http://www.gnu.org/licenses/ 21 | */ 22 | 23 | #ifndef __DONNA_IMAGE_MENU_ITEM_H__ 24 | #define __DONNA_IMAGE_MENU_ITEM_H__ 25 | 26 | #include 27 | 28 | G_BEGIN_DECLS 29 | 30 | typedef struct _DonnaImageMenuItem DonnaImageMenuItem; 31 | typedef struct _DonnaImageMenuItemPrivate DonnaImageMenuItemPrivate; 32 | typedef struct _DonnaImageMenuItemClass DonnaImageMenuItemClass; 33 | 34 | #define DONNA_TYPE_IMAGE_MENU_ITEM (donna_image_menu_item_get_type ()) 35 | #define DONNA_IMAGE_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DONNA_TYPE_IMAGE_MENU_ITEM, DonnaImageMenuItem)) 36 | #define DONNA_IMAGE_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DONNA_TYPE_IMAGE_MENU_ITEM, DonnaImageMenuItemClass)) 37 | #define DONNA_IS_IMAGE_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DONNA_TYPE_IMAGE_MENU_ITEM)) 38 | #define DONNA_IS_IMAGE_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), DONNA_TYPE_IMAGE_MENU_ITEM)) 39 | #define DONNA_IMAGE_MENU_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DONNA_TYPE_IMAGE_MENU_ITEM, DonnaImageMenuItemClass)) 40 | 41 | GType donna_image_menu_item_get_type (void) G_GNUC_CONST; 42 | 43 | /* keep in sync with DonnaContextIconSpecial in contextmenu.h */ 44 | typedef enum 45 | { 46 | DONNA_IMAGE_MENU_ITEM_IS_IMAGE = 0, 47 | DONNA_IMAGE_MENU_ITEM_IS_CHECK, 48 | DONNA_IMAGE_MENU_ITEM_IS_RADIO, 49 | _DONNA_IMAGE_MENU_ITEM_NB_IMAGE_SPECIAL 50 | } DonnaImageMenuItemImageSpecial; 51 | 52 | struct _DonnaImageMenuItem 53 | { 54 | /*< private >*/ 55 | GtkMenuItem item; 56 | DonnaImageMenuItemPrivate *priv; 57 | }; 58 | 59 | struct _DonnaImageMenuItemClass 60 | { 61 | GtkMenuItemClass parent_class; 62 | 63 | void (*load_submenu) (DonnaImageMenuItem *item, 64 | gboolean from_click); 65 | }; 66 | 67 | GtkWidget * donna_image_menu_item_new_with_label (const gchar *label); 68 | void donna_image_menu_item_set_image (DonnaImageMenuItem *item, 69 | GtkWidget *image); 70 | GtkWidget * donna_image_menu_item_get_image (DonnaImageMenuItem *item); 71 | void donna_image_menu_item_set_image_selected(DonnaImageMenuItem *item, 72 | GtkWidget *image); 73 | GtkWidget * donna_image_menu_item_get_image_selected(DonnaImageMenuItem *item); 74 | void donna_image_menu_item_set_image_special (DonnaImageMenuItem *item, 75 | DonnaImageMenuItemImageSpecial image); 76 | DonnaImageMenuItemImageSpecial donna_image_menu_item_get_image_special ( 77 | DonnaImageMenuItem *item); 78 | void donna_image_menu_item_set_is_active (DonnaImageMenuItem *item, 79 | gboolean is_active); 80 | gboolean donna_image_menu_item_get_is_active (DonnaImageMenuItem *item); 81 | void donna_image_menu_item_set_is_inconsistent (DonnaImageMenuItem *item, 82 | gboolean is_inconsistent); 83 | gboolean donna_image_menu_item_get_is_inconsistent (DonnaImageMenuItem *item); 84 | void donna_image_menu_item_set_is_combined (DonnaImageMenuItem *item, 85 | gboolean is_combined); 86 | gboolean donna_image_menu_item_get_is_combined (DonnaImageMenuItem *item); 87 | void donna_image_menu_item_set_is_combined_sensitive ( 88 | DonnaImageMenuItem *item, 89 | gboolean is_combined_sensitive); 90 | gboolean donna_image_menu_item_get_is_combined_sensitive ( 91 | DonnaImageMenuItem *item); 92 | void donna_image_menu_item_set_is_label_bold (DonnaImageMenuItem *item, 93 | gboolean is_bold); 94 | gboolean donna_image_menu_item_get_is_label_bold (DonnaImageMenuItem *item); 95 | void donna_image_menu_item_set_is_label_markup ( 96 | DonnaImageMenuItem *item, 97 | gboolean is_markup); 98 | gboolean donna_image_menu_item_get_is_label_markup ( 99 | DonnaImageMenuItem *item); 100 | void donna_image_menu_item_set_loading_submenu ( 101 | DonnaImageMenuItem *item, 102 | const gchar *label); 103 | 104 | G_END_DECLS 105 | 106 | #endif /* __DONNA_IMAGE_MENU_ITEM_H__ */ 107 | -------------------------------------------------------------------------------- /src/kalu/kalu-alpm.h: -------------------------------------------------------------------------------- 1 | /** 2 | * kalu - Copyright (C) 2012-2018 Olivier Brunel 3 | * 4 | * kalu-alpm.h 5 | * Copyright (C) 2012-2016 Olivier Brunel 6 | * 7 | * This file is part of kalu. 8 | * 9 | * kalu is free software: you can redistribute it and/or modify it under the 10 | * terms of the GNU General Public License as published by the Free Software 11 | * Foundation, either version 3 of the License, or (at your option) any later 12 | * version. 13 | * 14 | * kalu is distributed in the hope that it will be useful, but WITHOUT ANY 15 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 16 | * FOR A PARTICULAR PURPOSE. 17 | * See the GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License along with 20 | * kalu. If not, see http://www.gnu.org/licenses/ 21 | */ 22 | 23 | #ifndef _KALU_ALPM_H 24 | #define _KALU_ALPM_H 25 | 26 | /* glib */ 27 | #include 28 | 29 | /* alpm */ 30 | #include 31 | #include 32 | 33 | #ifndef DISABLE_UPDATER 34 | #include "conf.h" 35 | typedef struct { 36 | void (*dl_progress_cb) (const gchar *filename, off_t xfered, off_t total); 37 | void (*question_cb) (alpm_question_t *question); 38 | void (*log_cb) (alpm_loglevel_t level, const char *fmt, va_list args); 39 | void (*on_sync_dbs) (gpointer unused, gint nb); 40 | void (*on_sync_db_start) (gpointer unused, const gchar *name); 41 | void (*on_sync_db_end) (gpointer unused, guint result); 42 | pacman_config_t *pac_conf; 43 | } kalu_simul_t; 44 | #else 45 | typedef struct _kalu_simul_t kalu_simul_t; 46 | #endif 47 | 48 | typedef struct _kalu_alpm_t { 49 | char *dbpath; /* the tmp-path where we copied dbs */ 50 | alpm_handle_t *handle; 51 | alpm_transflag_t flags; 52 | #ifndef DISABLE_UPDATER 53 | kalu_simul_t *simulation; 54 | #endif 55 | } kalu_alpm_t; 56 | 57 | /* global variable */ 58 | extern unsigned short alpm_verbose; 59 | 60 | gboolean 61 | kalu_alpm_set_tmp_dbpath (const gchar *path); 62 | 63 | gboolean 64 | kalu_alpm_load (kalu_simul_t *simulation, const gchar *conffile, GString **_synced_dbs, GError **error); 65 | 66 | gboolean 67 | kalu_alpm_syncdbs (GString **_synced_dbs, GError **error); 68 | 69 | gboolean 70 | kalu_alpm_has_updates (alpm_list_t **packages, GError **error); 71 | 72 | gboolean 73 | kalu_alpm_has_updates_watched (alpm_list_t **packages, alpm_list_t *watched, GError **error); 74 | 75 | gboolean 76 | kalu_alpm_has_foreign (alpm_list_t **packages, alpm_list_t *ignore, GError **error); 77 | 78 | const gchar * 79 | kalu_alpm_get_dbpath (void); 80 | 81 | void 82 | kalu_alpm_rmdb (gboolean keep_tmp_dbpath); 83 | 84 | void 85 | kalu_alpm_free (void); 86 | 87 | #endif /* _KALU_ALPM_H */ 88 | -------------------------------------------------------------------------------- /src/kalu/kalu-updater.h: -------------------------------------------------------------------------------- 1 | /** 2 | * kalu - Copyright (C) 2012-2018 Olivier Brunel 3 | * 4 | * kalu-updater.h 5 | * Copyright (C) 2012-2016 Olivier Brunel 6 | * 7 | * This file is part of kalu. 8 | * 9 | * kalu is free software: you can redistribute it and/or modify it under the 10 | * terms of the GNU General Public License as published by the Free Software 11 | * Foundation, either version 3 of the License, or (at your option) any later 12 | * version. 13 | * 14 | * kalu is distributed in the hope that it will be useful, but WITHOUT ANY 15 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 16 | * FOR A PARTICULAR PURPOSE. 17 | * See the GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License along with 20 | * kalu. If not, see http://www.gnu.org/licenses/ 21 | */ 22 | 23 | #ifndef _KALU_KALU_UPDATER_H 24 | #define _KALU_KALU_UPDATER_H 25 | 26 | /* glib */ 27 | #include 28 | 29 | /* alpm */ 30 | #include 31 | #include 32 | 33 | typedef struct _provider_t { 34 | gchar *repo; 35 | gchar *pkg; 36 | gchar *version; 37 | } provider_t; 38 | 39 | #define KALU_UPDATER_ERROR g_quark_from_static_string ("kalu-updater error") 40 | 41 | #define KALU_TYPE_UPDATER (kalu_updater_get_type ()) 42 | #define KALU_UPDATER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), KALU_TYPE_UPDATER, KaluUpdater)) 43 | #define KALU_UPDATER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), KALU_TYPE_UPDATER, KaluUpdaterClass)) 44 | #define KALU_UPDATER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), KALU_TYPE_UPDATER, KaluUpdaterClass)) 45 | #define KALU_IS_UPDATER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), KALU_TYPE_UPDATER)) 46 | #define KALU_IS_UPDATER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), KALU_TYPE_UPDATER)) 47 | 48 | typedef struct _KaluUpdater KaluUpdater; 49 | typedef struct _KaluUpdaterClass KaluUpdaterClass; 50 | typedef struct _KaluUpdaterPrivate KaluUpdaterPrivate; 51 | 52 | typedef void (*KaluMethodCallback) (KaluUpdater *updater, const gchar *errmsg, 53 | gpointer data); 54 | typedef void (*KaluGetPackagesCallback) (KaluUpdater *updater, const gchar *errmsg, 55 | alpm_list_t *pkgs, gpointer data); 56 | 57 | typedef struct _method_callback_t { 58 | const gchar *name; 59 | gboolean is_running; 60 | KaluMethodCallback callback; 61 | gpointer data; 62 | } method_callback_t; 63 | 64 | /* object creation */ 65 | void 66 | kalu_updater_new (GCancellable *cancellable, GAsyncReadyCallback callback, gpointer data); 67 | 68 | KaluUpdater * 69 | kalu_updater_new_finish (GAsyncResult *res, GError **error); 70 | 71 | /* Init */ 72 | gboolean kalu_updater_init_upd (KaluUpdater *updater, 73 | gboolean downloadonly, 74 | GCancellable *cancellable, 75 | KaluMethodCallback callback, 76 | gpointer data, 77 | GError **error); 78 | 79 | 80 | /* InitAlpm */ 81 | gboolean kalu_updater_init_alpm (KaluUpdater *kupdater, 82 | gchar *rootdir, 83 | gchar *dbpath, 84 | gchar *logfile, 85 | gchar *gpgdir, 86 | alpm_list_t *hookdirs, 87 | alpm_list_t *cachedirs, 88 | alpm_siglevel_t siglevel, 89 | gchar *arch, 90 | gboolean checkspace, 91 | gboolean usesyslog, 92 | gdouble usedelta, 93 | alpm_list_t *ignorepkgs, 94 | alpm_list_t *ignoregroups, 95 | alpm_list_t *noupgrades, 96 | alpm_list_t *noextracts, 97 | GCancellable *cancellable, 98 | KaluMethodCallback callback, 99 | gpointer data, 100 | GError **error); 101 | 102 | 103 | /* AddDb */ 104 | gboolean kalu_updater_add_db (KaluUpdater *kupdater, 105 | gchar *name, 106 | alpm_siglevel_t siglevel, 107 | alpm_list_t *servers, 108 | GCancellable *cancellable, 109 | KaluMethodCallback callback, 110 | gpointer data, 111 | GError **error); 112 | 113 | 114 | /* SyncDbs */ 115 | gboolean kalu_updater_sync_dbs (KaluUpdater *kupdater, 116 | GCancellable *cancellable, 117 | KaluMethodCallback callback, 118 | gpointer data, 119 | GError **error); 120 | 121 | 122 | /* GetPackages */ 123 | gboolean kalu_updater_get_packages (KaluUpdater *kupdater, 124 | GCancellable *cancellable, 125 | KaluMethodCallback callback, 126 | gpointer data, 127 | GError **error); 128 | 129 | 130 | /* SysUpgrade */ 131 | 132 | gboolean kalu_updater_sysupgrade (KaluUpdater *kupdater, 133 | GCancellable *cancellable, 134 | KaluMethodCallback callback, 135 | gpointer data, 136 | GError **error); 137 | 138 | 139 | /* Abort */ 140 | 141 | gboolean kalu_updater_abort (KaluUpdater *kupdater, 142 | GCancellable *cancellable, 143 | KaluMethodCallback callback, 144 | gpointer data, 145 | GError **error); 146 | 147 | 148 | /* NoSysUpgrade */ 149 | 150 | gboolean kalu_updater_no_sysupgrade (KaluUpdater *kupdater, 151 | GCancellable *cancellable, 152 | KaluMethodCallback callback, 153 | gpointer data, 154 | GError **error); 155 | 156 | 157 | /* FreeAlpm */ 158 | gboolean kalu_updater_free_alpm (KaluUpdater *kupdater, 159 | GCancellable *cancellable, 160 | KaluMethodCallback callback, 161 | gpointer data, 162 | GError **error); 163 | 164 | #endif /* _KALU_KALU_UPDATER_H */ 165 | -------------------------------------------------------------------------------- /src/kalu/kalu.h: -------------------------------------------------------------------------------- 1 | /** 2 | * kalu - Copyright (C) 2012-2018 Olivier Brunel 3 | * 4 | * kalu.h 5 | * Copyright (C) 2012-2017 Olivier Brunel 6 | * 7 | * This file is part of kalu. 8 | * 9 | * kalu is free software: you can redistribute it and/or modify it under the 10 | * terms of the GNU General Public License as published by the Free Software 11 | * Foundation, either version 3 of the License, or (at your option) any later 12 | * version. 13 | * 14 | * kalu is distributed in the hope that it will be useful, but WITHOUT ANY 15 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 16 | * FOR A PARTICULAR PURPOSE. 17 | * See the GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License along with 20 | * kalu. If not, see http://www.gnu.org/licenses/ 21 | */ 22 | 23 | #ifndef _KALU_H 24 | #define _KALU_H 25 | 26 | /* C */ 27 | #include 28 | 29 | /* glib */ 30 | #include 31 | 32 | /* alpm */ 33 | #include 34 | #include 35 | 36 | /* kalu */ 37 | #include "shared.h" 38 | 39 | #if defined(GIT_VERSION) 40 | #undef PACKAGE_VERSION 41 | #define PACKAGE_VERSION GIT_VERSION 42 | #endif 43 | #define PACKAGE_TAG "Keeping Arch Linux Up-to-date" 44 | 45 | #ifndef DISABLE_GUI 46 | #define UPGRADES_NB_CONFLICT -2 /* set to nb_upgrades when conflict makes it 47 | impossible to get packages number */ 48 | #endif 49 | 50 | #ifndef NOTIFY_EXPIRES_DEFAULT 51 | #define NOTIFY_EXPIRES_DEFAULT -1 52 | #endif 53 | #ifndef NOTIFY_EXPIRES_NEVER 54 | #define NOTIFY_EXPIRES_NEVER 0 55 | #endif 56 | 57 | #define KALU_ERROR g_quark_from_static_string ("kalu error") 58 | 59 | #define FREE_PACKAGE_LIST(p) do { \ 60 | alpm_list_free_inner (p, (alpm_list_fn_free) free_package); \ 61 | alpm_list_free (p); \ 62 | p = NULL; \ 63 | } while(0) 64 | 65 | #define FREE_WATCHED_PACKAGE_LIST(p) do { \ 66 | alpm_list_free_inner (p, (alpm_list_fn_free) free_watched_package); \ 67 | alpm_list_free (p); \ 68 | p = NULL; \ 69 | } while(0) 70 | 71 | typedef enum { 72 | UPGRADE_NO_ACTION = 0, 73 | UPGRADE_ACTION_CMDLINE, 74 | #ifndef DISABLE_UPDATER 75 | UPGRADE_ACTION_KALU, 76 | #endif 77 | } upgrade_action_t; 78 | 79 | typedef enum { 80 | CHECK_UPGRADES = (1 << 0), 81 | CHECK_WATCHED = (1 << 1), 82 | CHECK_AUR = (1 << 2), 83 | CHECK_WATCHED_AUR = (1 << 3), 84 | CHECK_NEWS = (1 << 4), 85 | 86 | _CHECK_AUR_NOT_FOUND = (1 << 7) 87 | } check_t; 88 | 89 | typedef enum { 90 | DO_NOTHING = 0, 91 | DO_CHECK, 92 | DO_SYSUPGRADE, 93 | DO_SIMULATION, 94 | DO_TOGGLE_WINDOWS, 95 | DO_LAST_NOTIFS, 96 | DO_TOGGLE_PAUSE, 97 | DO_SAME_AS_ACTIVE, 98 | DO_EXIT 99 | } on_click_t; 100 | 101 | typedef enum { 102 | ICON_NONE = 0, 103 | ICON_KALU, 104 | ICON_USER 105 | } notif_icon_t; 106 | 107 | enum { 108 | IP_WHATEVER = 0, 109 | IPv4, 110 | IPv6 111 | }; 112 | 113 | #ifdef ENABLE_STATUS_NOTIFIER 114 | enum { 115 | SN_ICON_KALU = 0, 116 | SN_ICON_KALU_PAUSED, 117 | SN_ICON_KALU_GRAY, 118 | SN_ICON_KALU_GRAY_PAUSED, 119 | NB_SN_ICONS 120 | }; 121 | #define SN_ACTIVATE 1 122 | #define SN_SECONDARY_ACTIVATE 2 123 | #endif 124 | 125 | typedef enum { 126 | NO_TPL = -1, /* to indicate no fallback */ 127 | TPL_UPGRADES, 128 | TPL_WATCHED, 129 | TPL_AUR, 130 | TPL_AUR_NOT_FOUND, 131 | TPL_WATCHED_AUR, 132 | TPL_NEWS, 133 | _NB_TPL 134 | } tpl_t; 135 | 136 | /* template names in config (prefixed w/ "template-") */ 137 | const gchar *tpl_names[_NB_TPL]; 138 | 139 | typedef enum { 140 | FLD_TITLE, 141 | FLD_PACKAGE, 142 | FLD_SEP, 143 | _NB_FLD 144 | } fld_t; 145 | 146 | /* field names in config */ 147 | const gchar *fld_names[_NB_FLD]; 148 | 149 | typedef enum { 150 | TPL_SCE_UNDEFINED = 0, 151 | TPL_SCE_DEFAULT, 152 | TPL_SCE_FALLBACK, 153 | TPL_SCE_CUSTOM, 154 | TPL_SCE_NONE, 155 | _NB_TPL_SCE 156 | } tpl_sce_t; 157 | 158 | /* source names in config */ 159 | const gchar *tpl_sce_names[_NB_TPL_SCE]; 160 | 161 | struct field { 162 | const char *def; 163 | char *custom; 164 | tpl_sce_t source; 165 | }; 166 | 167 | typedef struct _templates_t { 168 | tpl_t fallback; 169 | struct field fields[_NB_TPL]; 170 | } templates_t; 171 | 172 | typedef struct _config_t { 173 | int is_debug; 174 | char *pacmanconf; 175 | check_t checks_manual; 176 | check_t checks_auto; 177 | int syncdbs_in_tooltip; 178 | int interval; 179 | int timeout; 180 | int has_skip; 181 | int skip_begin_hour; 182 | int skip_begin_minute; 183 | int skip_end_hour; 184 | int skip_end_minute; 185 | notif_icon_t notif_icon; 186 | char *notif_icon_user; 187 | int notif_icon_size; 188 | upgrade_action_t action; 189 | char *cmdline; 190 | char *cmdline_aur; 191 | #ifndef DISABLE_UPDATER 192 | alpm_list_t *cmdline_post; 193 | gboolean confirm_post; 194 | #endif 195 | gboolean check_pacman_conflict; 196 | on_click_t on_sgl_click; 197 | on_click_t on_dbl_click; 198 | on_click_t on_mdl_click; 199 | on_click_t on_sgl_click_paused; 200 | on_click_t on_dbl_click_paused; 201 | on_click_t on_mdl_click_paused; 202 | int use_ip; 203 | gboolean auto_notifs; 204 | gboolean notif_buttons; 205 | 206 | templates_t templates[_NB_TPL]; 207 | 208 | alpm_list_t *aur_ignore; 209 | 210 | alpm_list_t *watched; 211 | alpm_list_t *watched_aur; 212 | 213 | char *news_last; 214 | alpm_list_t *news_read; 215 | #ifndef DISABLE_GUI 216 | char *cmdline_link; 217 | #endif 218 | 219 | gboolean is_curl_init; 220 | #ifndef DISABLE_GUI 221 | alpm_list_t *last_notifs; 222 | #endif 223 | #ifndef DISABLE_UPDATER 224 | char *color_unimportant; 225 | char *color_info; 226 | char *color_warning; 227 | char *color_error; 228 | gboolean auto_show_log; 229 | #endif 230 | } config_t; 231 | 232 | typedef struct _watched_package_t { 233 | char *name; 234 | char *version; 235 | } watched_package_t; 236 | 237 | typedef struct _kalu_package_t { 238 | char *repo; 239 | char *name; 240 | char *desc; 241 | char *old_version; 242 | char *new_version; 243 | guint dl_size; 244 | guint old_size; /* old installed size */ 245 | guint new_size; /* new installed size */ 246 | } kalu_package_t; 247 | 248 | typedef enum { 249 | SKIP_UNKNOWN = 0, 250 | SKIP_BEGIN, 251 | SKIP_END 252 | } skip_next_t; 253 | 254 | typedef struct _kalpm_state_t { 255 | gboolean is_paused; 256 | skip_next_t skip_next; 257 | guint timeout_skip; 258 | gint is_busy; 259 | guint timeout; 260 | guint timeout_icon; 261 | GDateTime *last_check; 262 | GString *synced_dbs; 263 | gint nb_upgrades; 264 | gint nb_watched; 265 | gint nb_aur; 266 | gint nb_aur_not_found; 267 | gint nb_watched_aur; 268 | gint nb_news; 269 | } kalpm_state_t; 270 | 271 | typedef struct _notif_t { 272 | check_t type; 273 | gchar *summary; 274 | gchar *text; 275 | gpointer data; 276 | } notif_t; 277 | 278 | /* global variable */ 279 | extern config_t *config; 280 | 281 | void debug (const char *fmt, ...); 282 | 283 | void free_package (kalu_package_t *package); 284 | void free_watched_package (watched_package_t *w_pkg); 285 | 286 | void kalu_check_work (gboolean is_auto); 287 | 288 | #endif /* _KALU_H */ 289 | -------------------------------------------------------------------------------- /src/kalu/news.h: -------------------------------------------------------------------------------- 1 | /** 2 | * kalu - Copyright (C) 2012-2018 Olivier Brunel 3 | * 4 | * news.h 5 | * Copyright (C) 2012-2014 Olivier Brunel 6 | * 7 | * This file is part of kalu. 8 | * 9 | * kalu is free software: you can redistribute it and/or modify it under the 10 | * terms of the GNU General Public License as published by the Free Software 11 | * Foundation, either version 3 of the License, or (at your option) any later 12 | * version. 13 | * 14 | * kalu is distributed in the hope that it will be useful, but WITHOUT ANY 15 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 16 | * FOR A PARTICULAR PURPOSE. 17 | * See the GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License along with 20 | * kalu. If not, see http://www.gnu.org/licenses/ 21 | */ 22 | 23 | #ifndef _KALU_NEWS_H 24 | #define _KALU_NEWS_H 25 | 26 | /* glib */ 27 | #include 28 | 29 | /* alpm list */ 30 | #include 31 | 32 | gboolean 33 | news_has_updates (alpm_list_t **titles, 34 | gchar **xml_news, 35 | GError **error); 36 | 37 | gboolean 38 | news_show (gchar *xml_news, gboolean only_updates, GError **error); 39 | 40 | gboolean 41 | show_help (GError **error); 42 | 43 | gboolean 44 | show_history (GError **error); 45 | 46 | void 47 | show_pacman_conflict (void); 48 | 49 | #endif /* _KALU_NEWS_H */ 50 | -------------------------------------------------------------------------------- /src/kalu/preferences.h: -------------------------------------------------------------------------------- 1 | /** 2 | * kalu - Copyright (C) 2012-2018 Olivier Brunel 3 | * 4 | * preferences.h 5 | * Copyright (C) 2012-2014 Olivier Brunel 6 | * 7 | * This file is part of kalu. 8 | * 9 | * kalu is free software: you can redistribute it and/or modify it under the 10 | * terms of the GNU General Public License as published by the Free Software 11 | * Foundation, either version 3 of the License, or (at your option) any later 12 | * version. 13 | * 14 | * kalu is distributed in the hope that it will be useful, but WITHOUT ANY 15 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 16 | * FOR A PARTICULAR PURPOSE. 17 | * See the GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License along with 20 | * kalu. If not, see http://www.gnu.org/licenses/ 21 | */ 22 | 23 | #ifndef _KALU_PREFERENCES_H 24 | #define _KALU_PREFERENCES_H 25 | 26 | void 27 | show_prefs (void); 28 | 29 | #endif /* _KALU_PREFERENCES_H */ 30 | -------------------------------------------------------------------------------- /src/kalu/rt_timeout.c: -------------------------------------------------------------------------------- 1 | /** 2 | * kalu - Copyright (C) 2012-2018 Olivier Brunel 3 | * 4 | * rt_timeout.c 5 | * Copyright (C) 2013-2018 Olivier Brunel 6 | * 7 | * This file is part of kalu. 8 | * 9 | * kalu is free software: you can redistribute it and/or modify it under the 10 | * terms of the GNU General Public License as published by the Free Software 11 | * Foundation, either version 3 of the License, or (at your option) any later 12 | * version. 13 | * 14 | * kalu is distributed in the hope that it will be useful, but WITHOUT ANY 15 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 16 | * FOR A PARTICULAR PURPOSE. 17 | * See the GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License along with 20 | * kalu. If not, see http://www.gnu.org/licenses/ 21 | */ 22 | 23 | #include 24 | #include /* close() */ 25 | #include 26 | #include "rt_timeout.h" 27 | 28 | struct _RtTimeoutSource 29 | { 30 | GSource source; 31 | GPollFD pollfd; 32 | guint interval; 33 | }; 34 | 35 | static gboolean rt_timeout_prepare (GSource *source, gint *timeout); 36 | static gboolean rt_timeout_check (GSource *source); 37 | static gboolean rt_timeout_dispatch (GSource *source, GSourceFunc callback, gpointer data); 38 | static void rt_timeout_finalize (GSource *source); 39 | 40 | static GSourceFuncs rt_timeout_funcs = 41 | { 42 | .prepare = rt_timeout_prepare, 43 | .check = rt_timeout_check, 44 | .dispatch = rt_timeout_dispatch, 45 | .finalize = rt_timeout_finalize 46 | }; 47 | 48 | static gboolean 49 | rt_timeout_prepare (GSource *source __attribute__ ((unused)), gint *timeout) 50 | { 51 | *timeout = -1; 52 | return FALSE; 53 | } 54 | 55 | static gboolean 56 | rt_timeout_check (GSource *source) 57 | { 58 | RtTimeoutSource *sce = (RtTimeoutSource *) source; 59 | return (sce->pollfd.revents & G_IO_IN); 60 | } 61 | 62 | #define SECOND 1000000000 63 | static void set_value (struct timespec *tp, guint ms) 64 | { 65 | time_t sec; 66 | long nsec; 67 | 68 | sec = ms / 1000; 69 | nsec = (ms - 1000 * sec) * 1000000; 70 | 71 | clock_gettime (CLOCK_REALTIME, tp); 72 | tp->tv_sec += sec; 73 | if (tp->tv_nsec + nsec > SECOND) 74 | { 75 | ++tp->tv_sec; 76 | nsec -= SECOND; 77 | } 78 | tp->tv_nsec += nsec; 79 | } 80 | 81 | static gboolean 82 | rt_timeout_dispatch (GSource *source, GSourceFunc callback, gpointer data) 83 | { 84 | gboolean again; 85 | 86 | again = callback (data); 87 | if (again) 88 | { 89 | RtTimeoutSource *sce = (RtTimeoutSource *) source; 90 | struct itimerspec ts; 91 | 92 | set_value (&ts.it_value, sce->interval); 93 | ts.it_interval.tv_sec = 0; 94 | ts.it_interval.tv_nsec = 0; 95 | if (timerfd_settime (sce->pollfd.fd, TFD_TIMER_ABSTIME, &ts, NULL) == -1) 96 | again = FALSE; 97 | } 98 | return again; 99 | } 100 | 101 | static void 102 | rt_timeout_finalize (GSource *source) 103 | { 104 | RtTimeoutSource *sce = (RtTimeoutSource *) source; 105 | close (sce->pollfd.fd); 106 | } 107 | 108 | guint 109 | rt_timeout_add (guint interval, GSourceFunc function, gpointer data) 110 | { 111 | GSource *source; 112 | RtTimeoutSource *sce; 113 | guint id; 114 | struct itimerspec ts; 115 | 116 | if (interval == 0) 117 | return 0; 118 | 119 | source = g_source_new (&rt_timeout_funcs, sizeof (RtTimeoutSource)); 120 | sce = (RtTimeoutSource *) source; 121 | 122 | sce->pollfd.fd = timerfd_create (CLOCK_REALTIME, TFD_NONBLOCK); 123 | if (sce->pollfd.fd == -1) 124 | { 125 | g_source_unref (source); 126 | return 0; 127 | } 128 | set_value (&ts.it_value, interval); 129 | ts.it_interval.tv_sec = 0; 130 | ts.it_interval.tv_nsec = 0; 131 | if (timerfd_settime (sce->pollfd.fd, TFD_TIMER_ABSTIME, &ts, NULL) == -1) 132 | { 133 | g_source_unref (source); 134 | return 0; 135 | } 136 | 137 | sce->pollfd.events = G_IO_IN | G_IO_ERR; 138 | g_source_add_poll (source, &sce->pollfd); 139 | 140 | sce->interval = interval; 141 | g_source_set_callback (source, function, data, NULL); 142 | 143 | id = g_source_attach (source, NULL); 144 | g_source_unref (source); 145 | return id; 146 | } 147 | -------------------------------------------------------------------------------- /src/kalu/rt_timeout.h: -------------------------------------------------------------------------------- 1 | /** 2 | * kalu - Copyright (C) 2012-2018 Olivier Brunel 3 | * 4 | * rt_timeout.h 5 | * Copyright (C) 2013-2018 Olivier Brunel 6 | * 7 | * This file is part of kalu. 8 | * 9 | * kalu is free software: you can redistribute it and/or modify it under the 10 | * terms of the GNU General Public License as published by the Free Software 11 | * Foundation, either version 3 of the License, or (at your option) any later 12 | * version. 13 | * 14 | * kalu is distributed in the hope that it will be useful, but WITHOUT ANY 15 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 16 | * FOR A PARTICULAR PURPOSE. 17 | * See the GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License along with 20 | * kalu. If not, see http://www.gnu.org/licenses/ 21 | */ 22 | 23 | #ifndef _KALU_RT_TIMEOUT_H 24 | #define _KALU_RT_TIMEOUT_H 25 | 26 | /* glib */ 27 | #include 28 | 29 | typedef struct _RtTimeoutSource RtTimeoutSource; 30 | 31 | guint rt_timeout_add (guint interval, GSourceFunc function, gpointer data); 32 | 33 | #endif /* _KALU_RT_TIMEOUT_H */ 34 | -------------------------------------------------------------------------------- /src/kalu/shared.c: -------------------------------------------------------------------------------- 1 | /** 2 | * kalu - Copyright (C) 2012-2018 Olivier Brunel 3 | * 4 | * shared.c 5 | * Copyright (C) 2012-2014 Olivier Brunel 6 | * 7 | * This file is part of kalu. 8 | * 9 | * kalu is free software: you can redistribute it and/or modify it under the 10 | * terms of the GNU General Public License as published by the Free Software 11 | * Foundation, either version 3 of the License, or (at your option) any later 12 | * version. 13 | * 14 | * kalu is distributed in the hope that it will be useful, but WITHOUT ANY 15 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 16 | * FOR A PARTICULAR PURPOSE. 17 | * See the GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License along with 20 | * kalu. If not, see http://www.gnu.org/licenses/ 21 | */ 22 | 23 | /* C */ 24 | #include 25 | #include 26 | 27 | /* alpm */ 28 | #include 29 | 30 | /* kalu */ 31 | #include "config.h" 32 | #include "shared.h" 33 | 34 | void * 35 | _alloc (size_t len, int zero) 36 | { 37 | void *ptr; 38 | 39 | ptr = malloc (len); 40 | if (!ptr) 41 | { 42 | exit (255); 43 | } 44 | if (zero) 45 | { 46 | memzero (ptr, len); 47 | } 48 | return ptr; 49 | } 50 | 51 | void * 52 | _realloc (void *ptr, size_t len) 53 | { 54 | ptr = realloc (ptr, len); 55 | if (!ptr) 56 | { 57 | exit (255); 58 | } 59 | return ptr; 60 | } 61 | 62 | void 63 | set_user_agent (void) 64 | { 65 | char ua[128]; 66 | struct utsname un; 67 | 68 | uname (&un); 69 | snprintf (ua, 128, "kalu/%s (%s %s) libalpm/%s", 70 | PACKAGE_VERSION, un.sysname, un.machine, alpm_version ()); 71 | setenv ("HTTP_USER_AGENT", ua, 0); 72 | } 73 | -------------------------------------------------------------------------------- /src/kalu/shared.h: -------------------------------------------------------------------------------- 1 | /** 2 | * kalu - Copyright (C) 2012-2018 Olivier Brunel 3 | * 4 | * shared.h 5 | * Copyright (C) 2012-2016 Olivier Brunel 6 | * 7 | * This file is part of kalu. 8 | * 9 | * kalu is free software: you can redistribute it and/or modify it under the 10 | * terms of the GNU General Public License as published by the Free Software 11 | * Foundation, either version 3 of the License, or (at your option) any later 12 | * version. 13 | * 14 | * kalu is distributed in the hope that it will be useful, but WITHOUT ANY 15 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 16 | * FOR A PARTICULAR PURPOSE. 17 | * See the GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License along with 20 | * kalu. If not, see http://www.gnu.org/licenses/ 21 | */ 22 | 23 | #ifndef _SHARED_H 24 | #define _SHARED_H 25 | 26 | /* C */ 27 | #include 28 | #include 29 | 30 | #ifdef ENABLE_NLS 31 | #include 32 | #include 33 | #define gettext_noop(s) s 34 | #define N_(s) gettext_noop (s) 35 | #define _(s) gettext (s) 36 | #define _c(c, s) pgettext (c, s) 37 | #define _n(s1, s2, n) ngettext (s1, s2, n) 38 | 39 | /* The separator between msgctxt and msgid in a .mo file. */ 40 | #define GETTEXT_CONTEXT_GLUE "\004" 41 | 42 | #define pgettext(c, s) \ 43 | pgettext_aux (NULL, c GETTEXT_CONTEXT_GLUE s, s, LC_MESSAGES) 44 | 45 | #ifdef __GNUC__ 46 | __inline 47 | #endif 48 | static const char * 49 | pgettext_aux (const char *domain, 50 | const char *msg_ctxt_id, 51 | const char *msgid, 52 | int category) 53 | { 54 | const char *translation = dcgettext (domain, msg_ctxt_id, category); 55 | if (translation == msg_ctxt_id) 56 | { 57 | return msgid; 58 | } 59 | else 60 | { 61 | return translation; 62 | } 63 | } 64 | 65 | #else /* ENABLE_NLS */ 66 | #define N_(s) s 67 | #define _(s) s 68 | #define _c(c, s) s 69 | #define _n(s1, s2, n) ((n == 1) ? s1 : s2) 70 | #endif /* ENABLE_NLS */ 71 | 72 | #define _UNUSED_ __attribute__ ((unused)) 73 | 74 | #define streq(s1, s2) (((s1) == NULL && (s2) == NULL) ? 1 \ 75 | : ((s1) == NULL || (s2) == NULL) ? 0 : strcmp ((s1), (s2)) == 0) 76 | #define streqn(s1, s2, n) (((s1) == NULL || (s2) == NULL) ? 0 \ 77 | : strncmp ((s1), (s2), (n)) == 0) 78 | #define memzero(x, l) (memset (x, 0, l)) 79 | #define zero(x) (memzero (&(x), sizeof (x))) 80 | 81 | #define new(type, len) \ 82 | (type *) _alloc (sizeof (type) * (size_t) (len), 0) 83 | #define new0(type, len) \ 84 | (type *) _alloc (sizeof (type) * (size_t) (len), 1) 85 | #define renew(type, len, ptr) \ 86 | (type *) _realloc (ptr, sizeof (type) * (size_t) (len)) 87 | 88 | #define FOR_LIST(i, val) \ 89 | for (i = (alpm_list_t *) (val); i; i = i->next) 90 | 91 | void *_alloc (size_t len, int zero); 92 | void *_realloc (void *ptr, size_t len); 93 | void set_user_agent (void); 94 | 95 | #endif /* _SHARED_H */ 96 | -------------------------------------------------------------------------------- /src/kalu/updater.h: -------------------------------------------------------------------------------- 1 | /** 2 | * kalu - Copyright (C) 2012-2018 Olivier Brunel 3 | * 4 | * updater.h 5 | * Copyright (C) 2012-2014 Olivier Brunel 6 | * 7 | * This file is part of kalu. 8 | * 9 | * kalu is free software: you can redistribute it and/or modify it under the 10 | * terms of the GNU General Public License as published by the Free Software 11 | * Foundation, either version 3 of the License, or (at your option) any later 12 | * version. 13 | * 14 | * kalu is distributed in the hope that it will be useful, but WITHOUT ANY 15 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 16 | * FOR A PARTICULAR PURPOSE. 17 | * See the GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License along with 20 | * kalu. If not, see http://www.gnu.org/licenses/ 21 | */ 22 | 23 | #ifndef _KALU_UPDATER_H 24 | #define _KALU_UPDATER_H 25 | 26 | /* glib */ 27 | #include 28 | 29 | /* alpm */ 30 | #include 31 | #include 32 | 33 | void 34 | updater_run (const gchar *conffile, alpm_list_t *cmdline_post); 35 | 36 | #endif /* _KALU_UPDATER_H */ 37 | -------------------------------------------------------------------------------- /src/kalu/util-gtk.c: -------------------------------------------------------------------------------- 1 | /** 2 | * kalu - Copyright (C) 2012-2018 Olivier Brunel 3 | * 4 | * util-gtk.c 5 | * Copyright (C) 2012-2014 Olivier Brunel 6 | * 7 | * This file is part of kalu. 8 | * 9 | * kalu is free software: you can redistribute it and/or modify it under the 10 | * terms of the GNU General Public License as published by the Free Software 11 | * Foundation, either version 3 of the License, or (at your option) any later 12 | * version. 13 | * 14 | * kalu is distributed in the hope that it will be useful, but WITHOUT ANY 15 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 16 | * FOR A PARTICULAR PURPOSE. 17 | * See the GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License along with 20 | * kalu. If not, see http://www.gnu.org/licenses/ 21 | */ 22 | 23 | #include 24 | 25 | /* C */ 26 | #include 27 | #include 28 | 29 | /* alpm list */ 30 | #include 31 | 32 | /* kalu */ 33 | #include "util-gtk.h" 34 | #include "util.h" 35 | #include "gui.h" /* show_notif() */ 36 | 37 | static void renderer_toggle_cb (GtkCellRendererToggle *, gchar *, GtkTreeModel *); 38 | 39 | void 40 | rend_size (GtkTreeViewColumn *column _UNUSED_, GtkCellRenderer *renderer, 41 | GtkTreeModel *store, GtkTreeIter *iter, int col, int is_unsigned) 42 | { 43 | GValue value = G_VALUE_INIT; 44 | double size; 45 | const char *unit; 46 | char buf[23]; 47 | 48 | gtk_tree_model_get_value (store, iter, col, &value); 49 | if (is_unsigned) 50 | { 51 | size = humanize_size (g_value_get_uint (&value), '\0', &unit); 52 | } 53 | else 54 | { 55 | size = humanize_size (g_value_get_int (&value), '\0', &unit); 56 | } 57 | snprint_size (buf, 23, size, unit); 58 | g_object_set (renderer, "text", buf, NULL); 59 | g_value_unset (&value); 60 | } 61 | 62 | GtkWidget * 63 | new_confirm ( 64 | const gchar *message, 65 | const gchar *submessage, 66 | const gchar *btn_yes_label, 67 | const gchar *btn_yes_image, 68 | const gchar *btn_no_label, 69 | const gchar *btn_no_image, 70 | GtkWidget *window 71 | ) 72 | { 73 | GtkWidget *dialog; 74 | GtkWidget *button; 75 | GtkWidget *image; 76 | 77 | if (NULL == submessage) 78 | { 79 | dialog = gtk_message_dialog_new_with_markup ( 80 | GTK_WINDOW (window), 81 | GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, 82 | GTK_MESSAGE_QUESTION, 83 | GTK_BUTTONS_NONE, 84 | NULL); 85 | gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG(dialog), message); 86 | } 87 | else 88 | { 89 | dialog = gtk_message_dialog_new ( 90 | GTK_WINDOW (window), 91 | GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, 92 | GTK_MESSAGE_QUESTION, 93 | GTK_BUTTONS_NONE, 94 | "%s", 95 | message); 96 | gtk_message_dialog_format_secondary_markup ( 97 | GTK_MESSAGE_DIALOG (dialog), 98 | "%s", 99 | submessage); 100 | } 101 | 102 | gtk_window_set_decorated (GTK_WINDOW (dialog), FALSE); 103 | gtk_window_set_skip_taskbar_hint (GTK_WINDOW (dialog), TRUE); 104 | gtk_window_set_skip_pager_hint (GTK_WINDOW (dialog), TRUE); 105 | 106 | button = gtk_dialog_add_button (GTK_DIALOG (dialog), 107 | (NULL == btn_no_label) ? _("No") : btn_no_label, 108 | GTK_RESPONSE_NO); 109 | image = gtk_image_new_from_icon_name ( 110 | (NULL == btn_no_image) ? "gtk-no" : btn_no_image, 111 | GTK_ICON_SIZE_MENU); 112 | gtk_button_set_image( GTK_BUTTON(button), image); 113 | gtk_button_set_always_show_image ((GtkButton *) button, TRUE); 114 | 115 | button = gtk_dialog_add_button (GTK_DIALOG (dialog), 116 | (NULL == btn_yes_label) ? _("Yes") : btn_yes_label, 117 | GTK_RESPONSE_YES); 118 | image = gtk_image_new_from_icon_name ( 119 | (NULL == btn_yes_image) ? "gtk-yes" : btn_yes_image, 120 | GTK_ICON_SIZE_MENU); 121 | gtk_button_set_image (GTK_BUTTON (button), image); 122 | gtk_button_set_always_show_image ((GtkButton *) button, TRUE); 123 | 124 | return dialog; 125 | } 126 | 127 | gboolean 128 | confirm ( 129 | const gchar *message, 130 | const gchar *submessage, 131 | const gchar *btn_yes_label, 132 | const gchar *btn_yes_image, 133 | const gchar *btn_no_label, 134 | const gchar *btn_no_image, 135 | GtkWidget *window 136 | ) 137 | { 138 | GtkWidget *dialog; 139 | gint rc; 140 | 141 | dialog = new_confirm (message, submessage, btn_yes_label, btn_yes_image, 142 | btn_no_label, btn_no_image, window); 143 | gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_NO); 144 | rc = gtk_dialog_run (GTK_DIALOG (dialog)); 145 | gtk_widget_destroy (dialog); 146 | return rc == GTK_RESPONSE_YES; 147 | } 148 | 149 | void 150 | show_error (const gchar *message, const gchar *submessage, GtkWindow *parent) 151 | { 152 | GtkWidget *dialog; 153 | 154 | if (NULL == submessage) 155 | { 156 | dialog = gtk_message_dialog_new_with_markup ( 157 | parent, 158 | GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, 159 | GTK_MESSAGE_ERROR, 160 | GTK_BUTTONS_OK, 161 | NULL); 162 | gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (dialog), message); 163 | } 164 | else 165 | { 166 | dialog = gtk_message_dialog_new ( 167 | parent, 168 | GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, 169 | GTK_MESSAGE_ERROR, 170 | GTK_BUTTONS_OK, 171 | "%s", 172 | message); 173 | gtk_message_dialog_format_secondary_markup ( 174 | GTK_MESSAGE_DIALOG (dialog), 175 | "%s", 176 | submessage); 177 | } 178 | 179 | gtk_window_set_decorated (GTK_WINDOW (dialog), FALSE); 180 | gtk_window_set_skip_taskbar_hint (GTK_WINDOW (dialog), TRUE); 181 | gtk_window_set_skip_pager_hint (GTK_WINDOW (dialog), TRUE); 182 | 183 | g_signal_connect (G_OBJECT (dialog), "response", 184 | G_CALLBACK (gtk_widget_destroy), NULL); 185 | gtk_widget_show (dialog); 186 | } 187 | 188 | NotifyNotification * 189 | new_notification (const gchar *summary, const gchar *text) 190 | { 191 | NotifyNotification *notification; 192 | 193 | notification = notify_notification_new (summary, text, NULL); 194 | if (config->notif_icon != ICON_NONE) 195 | { 196 | GdkPixbuf *pixbuf = NULL; 197 | 198 | if (config->notif_icon == ICON_USER) 199 | { 200 | GError *error = NULL; 201 | 202 | debug ("new notification, loading user icon: %s", 203 | config->notif_icon_user); 204 | pixbuf = gdk_pixbuf_new_from_file_at_size (config->notif_icon_user, 205 | config->notif_icon_size, -1, &error); 206 | if (!pixbuf) 207 | { 208 | debug ("new notification: failed to load user icon: %s", 209 | error->message); 210 | g_clear_error (&error); 211 | } 212 | } 213 | /* ICON_KALU || failed to load ICON_USER */ 214 | if (!pixbuf) 215 | { 216 | debug ("new notification: using kalu's icon"); 217 | pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), 218 | "kalu", config->notif_icon_size, GTK_ICON_LOOKUP_FORCE_SIZE, NULL); 219 | } 220 | notify_notification_set_image_from_pixbuf (notification, pixbuf); 221 | g_object_unref (pixbuf); 222 | } 223 | notify_notification_set_timeout (notification, config->timeout); 224 | return notification; 225 | } 226 | 227 | void 228 | notify_error (const gchar *summary, const gchar *text) 229 | { 230 | notif_t *notif; 231 | 232 | notif = new (notif_t, 1); 233 | notif->type = 0; 234 | notif->summary = strdup (summary); 235 | notif->text = (text) ? strdup (text) : NULL; 236 | notif->data = NULL; 237 | 238 | /* add the notif to the last of last notifications, so we can re-show it later */ 239 | debug ("adding new notif (%s) to last_notifs", notif->summary); 240 | config->last_notifs = alpm_list_add (config->last_notifs, notif); 241 | /* show it */ 242 | show_notif (notif); 243 | } 244 | 245 | static void 246 | renderer_toggle_cb (GtkCellRendererToggle *renderer _UNUSED_, gchar *path, 247 | GtkTreeModel *model) 248 | { 249 | GtkTreeIter iter; 250 | gboolean run; 251 | 252 | gtk_tree_model_get_iter_from_string (model, &iter, path); 253 | gtk_tree_model_get (model, &iter, 0, &run, -1); 254 | run = !run; 255 | gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, run, -1); 256 | } 257 | 258 | alpm_list_t * 259 | confirm_choices ( 260 | const gchar *message, 261 | const gchar *submessage, 262 | const gchar *btn_yes_label, 263 | const gchar *btn_yes_image, 264 | const gchar *btn_no_label, 265 | const gchar *btn_no_image, 266 | const gchar *chk_label, 267 | const gchar *choice_label, 268 | alpm_list_t *choices, 269 | GtkWidget *window 270 | ) 271 | { 272 | GtkWidget *dialog; 273 | int rc; 274 | alpm_list_t *choices_selected = NULL; 275 | 276 | dialog = new_confirm (message, submessage, btn_yes_label, btn_yes_image, 277 | btn_no_label, btn_no_image, window); 278 | gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_NO); 279 | 280 | /* content area: where we'll add our list */ 281 | GtkWidget *box; 282 | box = gtk_dialog_get_content_area (GTK_DIALOG (dialog)); 283 | 284 | /* liststore for the list */ 285 | GtkListStore *store; 286 | store = gtk_list_store_new (2, G_TYPE_BOOLEAN, G_TYPE_STRING); 287 | 288 | /* said list */ 289 | GtkWidget *list; 290 | list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store)); 291 | g_object_unref (store); 292 | 293 | /* a scrolledwindow for the list */ 294 | GtkWidget *scrolled; 295 | scrolled = gtk_scrolled_window_new ( 296 | gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (list)), 297 | gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (list))); 298 | gtk_box_pack_start (GTK_BOX (box), scrolled, TRUE, TRUE, 0); 299 | gtk_widget_set_size_request (scrolled, -1, 108); 300 | gtk_widget_show (scrolled); 301 | 302 | /* cell renderer & column(s) */ 303 | GtkCellRenderer *renderer; 304 | GtkTreeViewColumn *column; 305 | /* column: Run */ 306 | renderer = gtk_cell_renderer_toggle_new (); 307 | g_signal_connect (G_OBJECT (renderer), "toggled", 308 | G_CALLBACK (renderer_toggle_cb), (gpointer) store); 309 | column = gtk_tree_view_column_new_with_attributes ( 310 | chk_label, 311 | renderer, 312 | "active", 0, 313 | NULL); 314 | gtk_tree_view_append_column (GTK_TREE_VIEW (list), column); 315 | /* column: Package */ 316 | renderer = gtk_cell_renderer_text_new (); 317 | column = gtk_tree_view_column_new_with_attributes ( 318 | choice_label, 319 | renderer, 320 | "text", 1, 321 | NULL); 322 | gtk_tree_view_append_column (GTK_TREE_VIEW (list), column); 323 | 324 | /* eo.columns */ 325 | 326 | /* fill data */ 327 | GtkTreeIter iter; 328 | alpm_list_t *i; 329 | FOR_LIST (i, choices) 330 | { 331 | gtk_list_store_append (store, &iter); 332 | gtk_list_store_set (store, &iter, 333 | 0, TRUE, 334 | 1, i->data, 335 | -1); 336 | } 337 | 338 | gtk_container_add (GTK_CONTAINER (scrolled), list); 339 | gtk_widget_show (list); 340 | 341 | /* show it */ 342 | rc = gtk_dialog_run (GTK_DIALOG (dialog)); 343 | if (rc == GTK_RESPONSE_YES) 344 | { 345 | if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) 346 | { 347 | gboolean is_selected; 348 | const gchar *choice; 349 | while (1) 350 | { 351 | gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, 352 | 0, &is_selected, 353 | 1, &choice, 354 | -1); 355 | if (is_selected) 356 | { 357 | choices_selected = alpm_list_add (choices_selected, 358 | strdup (choice)); 359 | } 360 | if (!gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter)) 361 | { 362 | break; 363 | } 364 | } 365 | } 366 | } 367 | gtk_widget_destroy (dialog); 368 | return choices_selected; 369 | } 370 | -------------------------------------------------------------------------------- /src/kalu/util-gtk.h: -------------------------------------------------------------------------------- 1 | /** 2 | * kalu - Copyright (C) 2012-2018 Olivier Brunel 3 | * 4 | * util-gtk.h 5 | * Copyright (C) 2012-2014 Olivier Brunel 6 | * 7 | * This file is part of kalu. 8 | * 9 | * kalu is free software: you can redistribute it and/or modify it under the 10 | * terms of the GNU General Public License as published by the Free Software 11 | * Foundation, either version 3 of the License, or (at your option) any later 12 | * version. 13 | * 14 | * kalu is distributed in the hope that it will be useful, but WITHOUT ANY 15 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 16 | * FOR A PARTICULAR PURPOSE. 17 | * See the GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License along with 20 | * kalu. If not, see http://www.gnu.org/licenses/ 21 | */ 22 | 23 | #ifndef _KALU_UTIL_GTK_H 24 | #define _KALU_UTIL_GTK_H 25 | 26 | /* gtk */ 27 | #include 28 | 29 | /* notify */ 30 | #include 31 | 32 | void 33 | rend_size (GtkTreeViewColumn *column, GtkCellRenderer *renderer, 34 | GtkTreeModel *store, GtkTreeIter *iter, int col, int is_unsigned); 35 | 36 | GtkWidget * 37 | new_confirm (const gchar *message, 38 | const gchar *submessage, 39 | const gchar *btn_yes_label, 40 | const gchar *btn_yes_image, 41 | const gchar *btn_no_label, 42 | const gchar *btn_no_image, 43 | GtkWidget *window 44 | ); 45 | 46 | gboolean 47 | confirm (const gchar *message, 48 | const gchar *submessage, 49 | const gchar *btn_yes_label, 50 | const gchar *btn_yes_image, 51 | const gchar *btn_no_label, 52 | const gchar *btn_no_image, 53 | GtkWidget *window 54 | ); 55 | 56 | void 57 | show_error (const gchar *summary, const gchar *text, GtkWindow *parent); 58 | 59 | NotifyNotification * 60 | new_notification (const gchar *summary, const gchar *text); 61 | 62 | void 63 | notify_error (const gchar *summary, const gchar *text); 64 | 65 | alpm_list_t * 66 | confirm_choices (const gchar *message, 67 | const gchar *submessage, 68 | const gchar *btn_yes_label, 69 | const gchar *btn_yes_image, 70 | const gchar *btn_no_label, 71 | const gchar *btn_no_image, 72 | const gchar *chk_label, 73 | const gchar *choice_label, 74 | alpm_list_t *choices, 75 | GtkWidget *window 76 | ); 77 | 78 | #endif /* _KALU_UTIL_GTK_H */ 79 | -------------------------------------------------------------------------------- /src/kalu/util.c: -------------------------------------------------------------------------------- 1 | /** 2 | * kalu - Copyright (C) 2012-2018 Olivier Brunel 3 | * 4 | * util.c 5 | * Copyright (C) 2012-2017 Olivier Brunel 6 | * Copyright (c) 2006-2011 Pacman Development Team 7 | * 8 | * This file is part of kalu. 9 | * 10 | * kalu is free software: you can redistribute it and/or modify it under the 11 | * terms of the GNU General Public License as published by the Free Software 12 | * Foundation, either version 3 of the License, or (at your option) any later 13 | * version. 14 | * 15 | * kalu is distributed in the hope that it will be useful, but WITHOUT ANY 16 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 17 | * FOR A PARTICULAR PURPOSE. 18 | * See the GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License along with 21 | * kalu. If not, see http://www.gnu.org/licenses/ 22 | */ 23 | 24 | #include 25 | 26 | /* C */ 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | /* alpm */ 37 | #include 38 | 39 | /* kalu */ 40 | #include "kalu.h" 41 | #include "util.h" 42 | 43 | /** 44 | * Makes sure the path for the filename exists. that is, makes sure every 45 | * bits before the last / exists and is a folder 46 | */ 47 | gboolean 48 | ensure_path (char *path) 49 | { 50 | char *s, *p; 51 | struct stat stat_info; 52 | 53 | p = path + 1; /* skip the root */ 54 | while ((s = strchr (p, '/'))) 55 | { 56 | *s = '\0'; 57 | if (0 != stat (path, &stat_info)) 58 | { 59 | /* if does not exist, we create it */ 60 | if (errno == ENOENT) 61 | { 62 | debug ("mkdir %s", path); 63 | if (0 != mkdir (path, S_IRWXU | S_IRGRP | S_IWGRP | S_IROTH 64 | | S_IWOTH)) 65 | { 66 | *s = '/'; /* restore */ 67 | return FALSE; 68 | } 69 | } 70 | else 71 | { 72 | debug ("failed to stat %s: %s", path, strerror (errno)); 73 | *s = '/'; /* restore */ 74 | return FALSE; 75 | } 76 | } 77 | /* make sure it's a folder */ 78 | else if (!S_ISDIR (stat_info.st_mode)) 79 | { 80 | *s = '/'; /* restore */ 81 | return FALSE; 82 | } 83 | *s = '/'; /* restore */ 84 | p = s + 1; 85 | } 86 | return TRUE; 87 | } 88 | 89 | /******************************************************************************* 90 | * The following functions come from pacman's source code. (They might have 91 | * been (slightly) modified.) 92 | * 93 | * Copyright (c) 2006-2011 Pacman Development Team 94 | * Copyright (c) 2002-2006 by Judd Vinet 95 | * http://projects.archlinux.org/pacman.git 96 | * 97 | ******************************************************************************/ 98 | 99 | /** 100 | * Trim whitespace and newlines from a string 101 | */ 102 | char * 103 | strtrim (char *str) 104 | { 105 | char *pch = str; 106 | 107 | if (str == NULL || *str == '\0') 108 | { 109 | /* string is empty, so we're done. */ 110 | return str; 111 | } 112 | 113 | while (isspace ((unsigned char) *pch)) 114 | { 115 | pch++; 116 | } 117 | if (pch != str) 118 | { 119 | size_t len = strlen (pch); 120 | if (len) 121 | { 122 | memmove (str, pch, len + 1); 123 | } 124 | else 125 | { 126 | *str = '\0'; 127 | } 128 | } 129 | 130 | /* check if there wasn't anything but whitespace in the string. */ 131 | if (*str == '\0') 132 | { 133 | return str; 134 | } 135 | 136 | pch = (str + (strlen (str) - 1)); 137 | while (isspace ((unsigned char) *pch)) 138 | { 139 | pch--; 140 | } 141 | *++pch = '\0'; 142 | 143 | return str; 144 | } 145 | 146 | /** 147 | * Replace all occurances of 'needle' with 'replace' in 'str', returning 148 | * a new string (must be free'd) 149 | */ 150 | char 151 | *strreplace (const char *str, const char *needle, const char *replace) 152 | { 153 | const char *p = NULL, *q = NULL; 154 | char *newstr = NULL, *newp = NULL; 155 | alpm_list_t *i = NULL, *list = NULL; 156 | size_t needlesz = strlen (needle), replacesz = strlen (replace); 157 | size_t newsz; 158 | 159 | if (!str) 160 | { 161 | return NULL; 162 | } 163 | 164 | p = str; 165 | q = strstr (p, needle); 166 | while (q) 167 | { 168 | list = alpm_list_add (list, (char *) q); 169 | p = q + needlesz; 170 | q = strstr (p, needle); 171 | } 172 | 173 | /* no occurences of needle found */ 174 | if (!list) 175 | { 176 | return strdup (str); 177 | } 178 | /* size of new string = size of old string + "number of occurences of needle" 179 | * x "size difference between replace and needle" */ 180 | newsz = strlen (str) + 1 + alpm_list_count (list) * (replacesz - needlesz); 181 | newstr = new0 (char, newsz); 182 | if (!newstr) 183 | { 184 | return NULL; 185 | } 186 | 187 | p = str; 188 | newp = newstr; 189 | FOR_LIST (i, list) 190 | { 191 | q = i->data; 192 | if (q > p) 193 | { 194 | /* add chars between this occurence and last occurence, if any */ 195 | memcpy (newp, p, (size_t) (q - p)); 196 | newp += q - p; 197 | } 198 | memcpy (newp, replace, replacesz); 199 | newp += replacesz; 200 | p = q + needlesz; 201 | } 202 | alpm_list_free (list); 203 | 204 | if (*p) 205 | { 206 | /* add the rest of 'p' */ 207 | strcpy (newp, p); 208 | } 209 | 210 | return newstr; 211 | } 212 | 213 | gboolean 214 | trans_init (kalu_alpm_t *alpm, alpm_transflag_t flags, int check_valid, GError **error) 215 | { 216 | GError *local_err = NULL; 217 | 218 | if (!check_syncdbs (alpm, 0, check_valid, &local_err)) 219 | { 220 | g_propagate_error (error, local_err); 221 | return FALSE; 222 | } 223 | 224 | if (alpm_trans_init (alpm->handle, flags) == -1) 225 | { 226 | g_set_error (error, KALU_ERROR, 1, 227 | _("Failed to initiate transaction: %s"), 228 | alpm_strerror (alpm_errno (alpm->handle))); 229 | return FALSE; 230 | } 231 | 232 | return TRUE; 233 | } 234 | 235 | gboolean 236 | trans_release (kalu_alpm_t *alpm, GError **error) 237 | { 238 | if (alpm_trans_release (alpm->handle) == -1) 239 | { 240 | g_set_error (error, KALU_ERROR, 2, 241 | _("Failed to release transaction: %s"), 242 | alpm_strerror (alpm_errno (alpm->handle))); 243 | return FALSE; 244 | } 245 | return TRUE; 246 | } 247 | 248 | /** Converts sizes in bytes into human readable units. 249 | * 250 | * @param bytes the size in bytes 251 | * @param target_unit '\0' or a short label. If equal to one of the short unit 252 | * labels ('B', 'K', ...) bytes is converted to target_unit; if '\0', the first 253 | * unit which will bring the value to below a threshold of 2048 will be chosen. 254 | * @param long_labels whether to use short ("K") or long ("KiB") unit labels 255 | * @param label will be set to the appropriate unit label 256 | * 257 | * @return the size in the appropriate unit 258 | */ 259 | double 260 | humanize_size (off_t bytes, const char target_unit, const char **label) 261 | { 262 | static const char *labels[] = {"B", "KiB", "MiB", "GiB", 263 | "TiB", "PiB", "EiB", "ZiB", "YiB"}; 264 | static const int unitcount = sizeof (labels) / sizeof (labels[0]); 265 | 266 | double val = (double) bytes; 267 | int index; 268 | 269 | for (index = 0; index < unitcount - 1; index++) 270 | { 271 | if (target_unit != '\0' && labels[index][0] == target_unit) 272 | { 273 | break; 274 | } 275 | else if (target_unit == '\0' && val <= 2048.0 && val >= -2048.0) 276 | { 277 | break; 278 | } 279 | val /= 1024.0; 280 | } 281 | 282 | if (label) 283 | { 284 | *label = labels[index]; 285 | } 286 | 287 | return val; 288 | } 289 | 290 | /* does the same thing as 'rm -rf' */ 291 | int 292 | rmrf (const char *path) 293 | { 294 | int errflag = 0; 295 | struct dirent *dp; 296 | DIR *dirp; 297 | 298 | if (unlink (path)) 299 | { 300 | if (errno == ENOENT) 301 | { 302 | goto done; 303 | } 304 | else if (errno == EPERM) 305 | { 306 | /* fallthrough */ 307 | } 308 | else if (errno == EISDIR) 309 | { 310 | /* fallthrough */ 311 | } 312 | else if (errno == ENOTDIR) 313 | { 314 | errflag = 1; 315 | goto done; 316 | } 317 | else 318 | { 319 | /* not a directory */ 320 | errflag = 1; 321 | goto done; 322 | } 323 | 324 | dirp = opendir (path); 325 | if (!dirp) 326 | { 327 | errflag = 1; 328 | goto done; 329 | } 330 | for (dp = readdir (dirp); dp != NULL; dp = readdir (dirp)) 331 | { 332 | if (dp->d_ino) 333 | { 334 | if (!streq (dp->d_name, "..") && !streq (dp->d_name, ".")) 335 | { 336 | char name[PATH_MAX]; 337 | if (snprintf (name, PATH_MAX, "%s/%s", 338 | path, dp->d_name) < PATH_MAX) 339 | { 340 | errflag += rmrf (name); 341 | } 342 | else 343 | { 344 | ++errflag; 345 | } 346 | } 347 | } 348 | } 349 | closedir (dirp); 350 | if (rmdir (path)) 351 | { 352 | ++errflag; 353 | } 354 | 355 | } 356 | done: 357 | debug ("removing %s %s (%d)", 358 | path, 359 | (!errflag) ? "success" : "failed", 360 | errflag); 361 | return errflag; 362 | } 363 | 364 | gboolean 365 | check_syncdbs (kalu_alpm_t *alpm, size_t need_repos, int check_valid, GError **error) 366 | { 367 | alpm_list_t *i; 368 | alpm_list_t *sync_dbs = alpm_get_syncdbs (alpm->handle); 369 | 370 | if (need_repos && sync_dbs == NULL) 371 | { 372 | g_set_error (error, KALU_ERROR, 1, 373 | _("No usable package repositories configured")); 374 | return FALSE; 375 | } 376 | 377 | if (check_valid) 378 | { 379 | /* ensure all known dbs are valid */ 380 | FOR_LIST (i, sync_dbs) 381 | { 382 | alpm_db_t *db = i->data; 383 | if (alpm_db_get_valid (db)) 384 | { 385 | g_set_error (error, KALU_ERROR, 1, 386 | _("Database %s is not valid: %s"), 387 | alpm_db_get_name (db), 388 | alpm_strerror (alpm_errno (alpm->handle))); 389 | return FALSE; 390 | } 391 | } 392 | } 393 | return TRUE; 394 | } 395 | 396 | /******************************************************************************/ 397 | 398 | inline void 399 | snprint_size (char *buf, int buflen, double size, const char *unit) 400 | { 401 | const char *fmt; 402 | if (unit && *unit == 'B' && *(unit + 1) == '\0') 403 | { 404 | fmt = "%.0f %s"; 405 | } 406 | else 407 | { 408 | fmt = "%.2f %s"; 409 | } 410 | snprintf (buf, (size_t) buflen, fmt, size, unit); 411 | } 412 | 413 | void 414 | parse_tpl ( 415 | const char *tpl, 416 | char **text, 417 | unsigned int *len, 418 | unsigned int *alloc, 419 | replacement_t **_replacements, 420 | gboolean escaping 421 | ) 422 | { 423 | replacement_t *r, **replacements; 424 | const char *t; 425 | char *s; 426 | char *b; 427 | size_t l; 428 | char found; 429 | 430 | if (!tpl) 431 | return; 432 | 433 | for (t = tpl, s = *text + *len; *t; ++t) 434 | { 435 | found = 0; 436 | 437 | /* placeholder? */ 438 | if (*t == '$') 439 | { 440 | replacements = _replacements; 441 | for (r = *replacements; r; ++replacements, r = *replacements) 442 | { 443 | if (r->name == NULL || r->value == NULL) 444 | { 445 | continue; 446 | } 447 | 448 | l = strlen (r->name); 449 | if (strncmp (t + 1, r->name, l) == 0) 450 | { 451 | for (b = r->value; *b; ++b) 452 | { 453 | const gchar *esc[] = 454 | { 455 | "&", "&", 456 | "'", "'", 457 | "\"", """, 458 | "<", "<", 459 | ">", ">", 460 | NULL 461 | }; 462 | gchar *_s; 463 | unsigned int _l, i; 464 | 465 | _s = b; 466 | _l = 1; 467 | if (escaping && r->need_escaping) 468 | { 469 | const gchar **e; 470 | 471 | for (e = esc; *e; e += 2) 472 | { 473 | if (*_s == *e[0]) 474 | { 475 | _s = (gchar *) e[1]; 476 | _l = (unsigned int) strlen (_s); 477 | break; 478 | } 479 | } 480 | } 481 | 482 | /* enough memory? */ 483 | if (*len + _l >= *alloc) 484 | { 485 | *alloc += 1024; 486 | *text = renew (gchar, *alloc + 1, *text); 487 | s = *text + *len; 488 | } 489 | 490 | for (i = 0; i < _l; ++i, ++*len) 491 | *s++ = *_s++; 492 | } 493 | t += l; 494 | found = 1; 495 | break; 496 | } 497 | } 498 | } 499 | /* not a placeholder, or nothing known/supported, i.e. just a '$' */ 500 | if (found == 0) 501 | { 502 | /* copy character */ 503 | *s++ = *t; 504 | ++*len; 505 | } 506 | /* out of memory? */ 507 | if (*len >= *alloc) 508 | { 509 | *alloc += 1024; 510 | *text = renew (gchar, *alloc + 1, *text); 511 | s = *text + *len; 512 | } 513 | } 514 | 515 | *s = '\0'; 516 | } 517 | 518 | int 519 | watched_package_cmp (watched_package_t *w_pkg1, watched_package_t *w_pkg2) 520 | { 521 | int ret; 522 | ret = strcmp (w_pkg1->name, w_pkg2->name); 523 | if (ret == 0) 524 | { 525 | ret = strcmp (w_pkg1->version, w_pkg2->version); 526 | } 527 | return ret; 528 | } 529 | -------------------------------------------------------------------------------- /src/kalu/util.h: -------------------------------------------------------------------------------- 1 | /** 2 | * kalu - Copyright (C) 2012-2018 Olivier Brunel 3 | * 4 | * util.h 5 | * Copyright (C) 2012-2016 Olivier Brunel 6 | * 7 | * This file is part of kalu. 8 | * 9 | * kalu is free software: you can redistribute it and/or modify it under the 10 | * terms of the GNU General Public License as published by the Free Software 11 | * Foundation, either version 3 of the License, or (at your option) any later 12 | * version. 13 | * 14 | * kalu is distributed in the hope that it will be useful, but WITHOUT ANY 15 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 16 | * FOR A PARTICULAR PURPOSE. 17 | * See the GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License along with 20 | * kalu. If not, see http://www.gnu.org/licenses/ 21 | */ 22 | 23 | #ifndef _KALU_UTIL_H 24 | #define _KALU_UTIL_H 25 | 26 | /* glib */ 27 | #include 28 | 29 | /* alpm */ 30 | #include 31 | 32 | /* kalu */ 33 | #include "kalu.h" 34 | #include "kalu-alpm.h" 35 | 36 | typedef struct _replacement_t { 37 | const char *name; 38 | char *value; 39 | gboolean need_escaping; 40 | } replacement_t; 41 | 42 | gboolean 43 | ensure_path (char *path); 44 | 45 | char * 46 | strtrim (char *str); 47 | 48 | char 49 | *strreplace (const char *str, const char *needle, const char *replace); 50 | 51 | gboolean 52 | check_syncdbs (kalu_alpm_t *alpm, size_t need_repos, int check_valid, GError **error); 53 | 54 | gboolean 55 | trans_init (kalu_alpm_t *alpm, alpm_transflag_t flags, int check_valid, GError **error); 56 | 57 | gboolean 58 | trans_release (kalu_alpm_t *alpm, GError **error); 59 | 60 | double 61 | humanize_size(off_t bytes, const char target_unit, const char **label); 62 | 63 | int 64 | rmrf (const char *path); 65 | 66 | void 67 | snprint_size (char *buf, int buflen, double size, const char *unit); 68 | 69 | void 70 | parse_tpl (const char *tpl, char **text, unsigned int *len, unsigned int *alloc, 71 | replacement_t **replacements, gboolean escaping); 72 | 73 | int 74 | watched_package_cmp (watched_package_t *w_pkg1, watched_package_t *w_pkg2); 75 | 76 | #endif /* _KALU_UTIL_H */ 77 | -------------------------------------------------------------------------------- /src/kalu/watched.h: -------------------------------------------------------------------------------- 1 | /** 2 | * kalu - Copyright (C) 2012-2018 Olivier Brunel 3 | * 4 | * watched.h 5 | * Copyright (C) 2012-2014 Olivier Brunel 6 | * 7 | * This file is part of kalu. 8 | * 9 | * kalu is free software: you can redistribute it and/or modify it under the 10 | * terms of the GNU General Public License as published by the Free Software 11 | * Foundation, either version 3 of the License, or (at your option) any later 12 | * version. 13 | * 14 | * kalu is distributed in the hope that it will be useful, but WITHOUT ANY 15 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 16 | * FOR A PARTICULAR PURPOSE. 17 | * See the GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License along with 20 | * kalu. If not, see http://www.gnu.org/licenses/ 21 | */ 22 | 23 | #ifndef _KALU_WATCHED_H 24 | #define _KALU_WATCHED_H 25 | 26 | void watched_update (alpm_list_t *packages, gboolean is_aur); 27 | void watched_manage (gboolean is_aur); 28 | 29 | #endif /* _KALU_WATCHED_H */ 30 | --------------------------------------------------------------------------------