Add initial build files and enough code to launch a simple D-Bus daemon

This commit is contained in:
Richard Hughes 2015-02-26 13:07:40 +00:00
parent 863067a465
commit 8dbfb1c478
35 changed files with 2345 additions and 0 deletions

1
AUTHORS Normal file
View File

@ -0,0 +1 @@
Richard Hughes <richard@hughsie.com>

1
MAINTAINERS Normal file
View File

@ -0,0 +1 @@
Richard Hughes <richard@hughsie.com>

76
Makefile.am Normal file
View File

@ -0,0 +1,76 @@
AUTOMAKE_OPTIONS = 1.7
ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
SUBDIRS = \
po \
data \
man \
policy \
src
snapshot:
$(MAKE) dist distdir=$(PACKAGE)-$(VERSION)-`date +"%Y%m%d"`
EXTRA_DIST = \
COPYING \
MAINTAINERS \
AUTHORS \
README.md \
NEWS \
autogen.sh \
config.h \
intltool-extract.in \
intltool-merge.in \
intltool-update.in
MAINTAINERCLEANFILES = \
$(srcdir)/INSTALL \
$(srcdir)/ABOUT-NLS \
$(srcdir)/aclocal.m4 \
$(srcdir)/autoscan.log \
$(srcdir)/compile \
$(srcdir)/config.guess \
$(srcdir)/config.rpath \
$(srcdir)/config.h.in \
$(srcdir)/config.sub \
$(srcdir)/configure.scan \
$(srcdir)/depcomp \
$(srcdir)/install-sh \
$(srcdir)/ltmain.sh \
$(srcdir)/missing \
$(srcdir)/mkinstalldirs \
$(srcdir)/omf.make \
$(srcdir)/test-driver \
$(srcdir)/xmldocs.make \
$(srcdir)/gtk-doc.make \
$(srcdir)/ChangeLog \
$(srcdir)/po/Makefile.in.in~ \
$(srcdir)/fwupd-*.tar.* \
`find "$(srcdir)" -type f -name Makefile.in -print`
GITIGNOREFILES = \
.tx
distclean-local:
if test $(srdcir) = .; then :; else \
rm -f ChangeLog; \
fi
ChangeLog:
@echo Creating $@
@if test -d "$(srcdir)/.git"; then \
(GIT_DIR=$(top_srcdir)/.git ./missing --run git log e197d80c8937c622f21f569457d1bbd05746d951.. --stat -M -C --name-status --date=short --no-color) | fmt --split-only > $@.tmp \
&& mv -f $@.tmp $@ \
|| ($(RM) $@.tmp; \
echo Failed to generate ChangeLog, your ChangeLog may be outdated >&2; \
(test -f $@ || echo git-log is required to generate this file >> $@)); \
else \
test -f $@ || \
(echo A git checkout and git-log is required to generate ChangeLog >&2 && \
echo A git checkout and git-log is required to generate this file >> $@); \
fi
.PHONY: ChangeLog
-include $(top_srcdir)/git.mk

0
NEWS Normal file
View File

4
README.md Normal file
View File

@ -0,0 +1,4 @@
fwupd
=====
fwupd is a simple daemon to allow session software to update UEFI firmware.

28
autogen.sh Executable file
View File

@ -0,0 +1,28 @@
#!/bin/sh
# Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
#
# Run this to generate all the initial makefiles, etc.
#
# Licensed under the GNU General Public License Version 2
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
test -n "$srcdir" || srcdir=`dirname "$0"`
test -n "$srcdir" || srcdir=.
olddir=`pwd`
cd "$srcdir"
AUTORECONF=`which autoreconf`
if test -z $AUTORECONF; then
echo "*** No autoreconf found, please install it ***"
exit 1
fi
autopoint --force
ACLOCAL="${ACLOCAL-aclocal} $ACLOCAL_FLAGS" AUTOPOINT='intltoolize --automake --copy' autoreconf --force --install --verbose
cd "$olddir"
test -n "$NOCONFIGURE" || "$srcdir/configure" "$@"

117
configure.ac Normal file
View File

@ -0,0 +1,117 @@
# Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
AC_PREREQ(2.63)
AC_INIT([fwupd],[0.1.0],[http://www.freedesktop.org/software/fwupd/])
AC_CONFIG_SRCDIR(src)
AM_INIT_AUTOMAKE([1.9 no-dist-gzip dist-xz tar-ustar foreign])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIR([m4])
AC_PROG_LIBTOOL
m4_ifdef([GOBJECT_INTROSPECTION_CHECK], [GOBJECT_INTROSPECTION_CHECK([0.9.8])])
AM_CONDITIONAL(HAVE_INTROSPECTION, test "x$found_introspection" = xyes)
GLIB_GSETTINGS
# enable nice build output on automake1.11
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
AS_ALL_LINGUAS
AC_PROG_CC
AC_PROG_INSTALL
LT_INIT
AM_PROG_CC_C_O
IT_PROG_INTLTOOL([0.35.0])
AC_PATH_PROG(XSLTPROC, xsltproc)
dnl ---------------------------------------------------------------------------
dnl - Extra verbose warning switches
dnl ---------------------------------------------------------------------------
if test "$GCC" = "yes"; then
WARNINGFLAGS_C="$WARNINGFLAGS_C -Wall"
WARNINGFLAGS_C="$WARNINGFLAGS_C -Wcast-align -Wno-uninitialized"
WARNINGFLAGS_C="$WARNINGFLAGS_C -Wmissing-declarations"
WARNINGFLAGS_C="$WARNINGFLAGS_C -Wpointer-arith"
WARNINGFLAGS_C="$WARNINGFLAGS_C -Wcast-align"
WARNINGFLAGS_C="$WARNINGFLAGS_C -Wwrite-strings"
WARNINGFLAGS_C="$WARNINGFLAGS_C -Winit-self"
WARNINGFLAGS_C="$WARNINGFLAGS_C -Wreturn-type"
WARNINGFLAGS_C="$WARNINGFLAGS_C -Wformat-nonliteral"
WARNINGFLAGS_C="$WARNINGFLAGS_C -Wformat-security"
WARNINGFLAGS_C="$WARNINGFLAGS_C -Wmissing-include-dirs"
WARNINGFLAGS_C="$WARNINGFLAGS_C -Wmissing-format-attribute"
WARNINGFLAGS_C="$WARNINGFLAGS_C -Wclobbered"
WARNINGFLAGS_C="$WARNINGFLAGS_C -Wempty-body"
WARNINGFLAGS_C="$WARNINGFLAGS_C -Wignored-qualifiers"
WARNINGFLAGS_C="$WARNINGFLAGS_C -Wsign-compare"
WARNINGFLAGS_C="$WARNINGFLAGS_C -Wtype-limits"
WARNINGFLAGS_C="$WARNINGFLAGS_C -Wuninitialized"
WARNINGFLAGS_C="$WARNINGFLAGS_C -Waggregate-return"
WARNINGFLAGS_C="$WARNINGFLAGS_C -Wdeclaration-after-statement"
WARNINGFLAGS_C="$WARNINGFLAGS_C -Wshadow"
WARNINGFLAGS_C="$WARNINGFLAGS_C -Wno-strict-aliasing"
WARNINGFLAGS_C="$WARNINGFLAGS_C -Winline"
WARNINGFLAGS_C="$WARNINGFLAGS_C -Wmissing-parameter-type"
WARNINGFLAGS_C="$WARNINGFLAGS_C -Woverride-init"
else
WARNINGFLAGS_C=""
fi
AC_SUBST(WARNINGFLAGS_C)
dnl ---------------------------------------------------------------------------
dnl - gettext stuff
dnl ---------------------------------------------------------------------------
AM_GNU_GETTEXT_VERSION([0.17])
AM_GNU_GETTEXT([external])
GETTEXT_PACKAGE=AC_PACKAGE_NAME
AC_SUBST(GETTEXT_PACKAGE)
AC_DEFINE(GETTEXT_PACKAGE, "AC_PACKAGE_NAME", [foo])
# check for PIE (position independent executable) support
if test x$with_pic != xno; then
AX_CHECK_COMPILE_FLAG([-fPIE],
[AX_CHECK_LINK_FLAG([-fPIE -pie],
[PIE_CFLAGS="-fPIE" PIE_LDFLAGS="-pie"])])
AC_SUBST(PIE_CFLAGS)
AC_SUBST(PIE_LDFLAGS)
fi
# check for full RELRO (relocation read-only) support
AX_CHECK_LINK_FLAG([-Wl,-z,relro,-z,now],
[RELRO_LDFLAGS="-Wl,-z,relro,-z,now"])
AC_SUBST([RELRO_LDFLAGS])
dnl ---------------------------------------------------------------------------
dnl - Check library dependencies
dnl ---------------------------------------------------------------------------
PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.36.0 gobject-2.0 gthread-2.0 gio-2.0 >= 2.25.9 gio-unix-2.0)
PKG_CHECK_MODULES(GUDEV, gudev-1.0)
PKG_CHECK_MODULES(POLKIT, polkit-gobject-1 >= 0.103)
AC_PATH_PROG(DOCBOOK2MAN, docbook2man)
dnl ---------------------------------------------------------------------------
dnl - Makefiles, etc.
dnl ---------------------------------------------------------------------------
AC_CONFIG_FILES([
Makefile
man/Makefile
data/Makefile
data/tests/Makefile
policy/Makefile
po/Makefile.in
src/Makefile
])
AC_OUTPUT
dnl ==========================================================================
echo "
fwupd $VERSION
=================
prefix: ${prefix}
datadir: ${datadir}
compiler: ${CC}
cflags: ${CFLAGS}
cppflags: ${CPPFLAGS}
"

51
contrib/fwupd.spec.in Normal file
View File

@ -0,0 +1,51 @@
%define alphatag #ALPHATAG#
Summary: Firmware update daemon
Name: fwupd
Version: #VERSION#
Release: 0.#BUILD#%{?alphatag}%{?dist}
License: GPLv2+
URL: https://github.com/hughsie/fwupd
Source0: http://www.freedesktop.org/software/releases/%{name}-%{version}.tar.xz
BuildRequires: docbook-utils
BuildRequires: gettext
BuildRequires: glib2-devel
BuildRequires: intltool
BuildRequires: libgudev1-devel
BuildRequires: polkit-devel >= 0.103
%description
fwupd is a daemon to allow session software to update UEFI firmware.
%prep
%setup -q
%build
%configure \
--disable-static \
--disable-rpath \
--disable-silent-rules \
--disable-dependency-tracking
make %{?_smp_mflags}
%install
make install DESTDIR=$RPM_BUILD_ROOT
%find_lang %{name}
%files -f %{name}.lang
%doc README.md AUTHORS NEWS COPYING
%{_libexecdir}/fwupd
%{_bindir}/fwupdmgr
%{_sysconfdir}/dbus-1/system.d/org.freedesktop.fwupd.conf
%{_datadir}/dbus-1/interfaces/org.freedesktop.fwupd.xml
%{_datadir}/polkit-1/actions/org.freedesktop.fwupd.policy
%{_datadir}/dbus-1/system-services/org.freedesktop.fwupd.service
%{_datadir}/man/man1/fwupdmgr.1.gz
%changelog
* #LONGDATE# Richard Hughes <richard@hughsie.com> #VERSION#-0.#BUILD##ALPHATAG#
- Update from git

20
data/Makefile.am Normal file
View File

@ -0,0 +1,20 @@
SUBDIRS = tests
dbusdir = $(sysconfdir)/dbus-1/system.d
dist_dbus_DATA = org.freedesktop.fwupd.conf
dbusservicemaindir = $(datadir)/dbus-1/system-services
dbusservicemain_in_files = org.freedesktop.fwupd.service.in
dbusservicemain_DATA = $(dbusservicemain_in_files:.service.in=.service)
$(dbusservicemain_DATA): $(dbusservicemain_in_files) Makefile
@sed -e "s|\@servicedir\@|$(libexecdir)|" $< | \
sed -e "s|\@daemon_user\@|$(daemon_user)|" > $@
EXTRA_DIST = \
$(dbusservicemain_in_files)
DISTCLEANFILES = \
$(dbusservicemain_DATA) \
$(systemdservicemain_DATA)
-include $(top_srcdir)/git.mk

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?> <!-- -*- XML -*- -->
<!DOCTYPE busconfig PUBLIC
"-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
<!-- This configuration file specifies the required security policies
for the fwupd to work. -->
<!-- Only user root can own the fwupd service -->
<policy user="root">
<allow own="org.freedesktop.fwupd"/>
</policy>
<!-- Allow anyone to call into the service - we'll reject callers using PolicyKit -->
<policy context="default">
<allow send_destination="org.freedesktop.fwupd"
send_interface="org.freedesktop.fwupd"/>
<allow send_destination="org.freedesktop.fwupd"
send_interface="org.freedesktop.DBus.Properties"/>
<allow send_destination="org.freedesktop.fwupd"
send_interface="org.freedesktop.DBus.Introspectable"/>
<allow send_destination="org.freedesktop.fwupd"
send_interface="org.freedesktop.DBus.Peer"/>
</policy>
</busconfig>

View File

@ -0,0 +1,4 @@
[D-BUS Service]
Name=org.freedesktop.fwupd
Exec=@servicedir@/fwupd
#SystemdService=fwupd.service

5
data/tests/Makefile.am Normal file
View File

@ -0,0 +1,5 @@
test_files =
EXTRA_DIST = $(test_files)
-include $(top_srcdir)/git.mk

200
git.mk Normal file
View File

@ -0,0 +1,200 @@
# git.mk
#
# Copyright 2009, Red Hat, Inc.
# Written by Behdad Esfahbod
#
# Copying and distribution of this file, with or without modification,
# are permitted in any medium without royalty provided the copyright
# notice and this notice are preserved.
#
# The canonical source for this file is pango/git.mk, or whereever the
# header of pango/git.mk suggests in the future.
#
# To use in your project, import this file in your git repo's toplevel,
# then do "make -f git.mk". This modifies all Makefile.am files in
# your project to include git.mk.
#
# This enables automatic .gitignore generation. If you need to ignore
# more files, add them to the GITIGNOREFILES variable in your Makefile.am.
# But think twice before doing that. If a file has to be in .gitignore,
# chances are very high that it's a generated file and should be in one
# of MOSTLYCLEANFILES, CLEANFILES, DISTCLEANFILES, or MAINTAINERCLEANFILES.
#
# The only case that you need to manually add a file to GITIGNOREFILES is
# when remove files in one of mostlyclean-local, clean-local, distclean-local,
# or maintainer-clean-local.
#
# Note that for files like editor backup, etc, there are better places to
# ignore them. See "man gitignore".
#
# If "make maintainer-clean" removes the files but they are not recognized
# by this script (that is, if "git status" shows untracked files still), send
# me the output of "git status" as well as your Makefile.am and Makefile for
# the directories involved.
#
# For a list of toplevel files that should be in MAINTAINERCLEANFILES, see
# pango/Makefile.am.
#
# Don't EXTRA_DIST this file. It is supposed to only live in git clones,
# not tarballs. It serves no useful purpose in tarballs and clutters the
# build dir.
#
# This file knows how to handle autoconf, automake, libtool, gtk-doc,
# gnome-doc-utils, mallard, intltool, gsettings.
#
#
# KNOWN ISSUES:
#
# - Recursive configure doesn't work as $(top_srcdir)/git.mk inside the
# submodule doesn't find us. If you have configure.{in,ac} files in
# subdirs, add a proxy git.mk file in those dirs that simply does:
# "include $(top_srcdir)/../git.mk". Add more ..'s to your taste.
# And add those files to git. See vte/gnome-pty-helper/git.mk for
# example.
#
# ChangeLog
#
# - 2010-12-06 Add support for Mallard docs
# - 2010-12-06 Start this change log
git-all: git-mk-install
git-mk-install:
@echo Installing git makefile
@any_failed=; find $(top_srcdir) -name Makefile.am | while read x; do \
if grep 'include .*/git.mk' $$x >/dev/null; then \
echo $$x already includes git.mk; \
else \
failed=; \
echo "Updating $$x"; \
{ cat $$x; \
echo ''; \
echo '-include $$(top_srcdir)/git.mk'; \
} > $$x.tmp || failed=1; \
if test x$$failed = x; then \
mv $$x.tmp $$x || failed=1; \
fi; \
if test x$$failed = x; then : else \
echo Failed updating $$x; >&2 \
any_failed=1; \
fi; \
fi; done; test -z "$$any_failed"
.PHONY: git-all git-mk-install
### .gitignore generation
$(srcdir)/.gitignore: Makefile.am $(top_srcdir)/git.mk
$(AM_V_GEN) \
{ \
if test "x$(DOC_MODULE)" = x -o "x$(DOC_MAIN_SGML_FILE)" = x; then :; else \
for x in \
$(DOC_MODULE)-decl-list.txt \
$(DOC_MODULE)-decl.txt \
tmpl/$(DOC_MODULE)-unused.sgml \
"tmpl/*.bak" \
xml html \
; do echo /$$x; done; \
fi; \
if test "x$(DOC_MODULE)$(DOC_ID)" = x -o "x$(DOC_LINGUAS)" = x; then :; else \
for x in \
$(_DOC_C_DOCS) \
$(_DOC_LC_DOCS) \
$(_DOC_OMF_ALL) \
$(_DOC_DSK_ALL) \
$(_DOC_HTML_ALL) \
$(_DOC_MOFILES) \
$(_DOC_POFILES) \
$(DOC_H_FILE) \
"*/.xml2po.mo" \
"*/*.omf.out" \
; do echo /$$x; done; \
fi; \
if test "x$(gsettings_SCHEMAS)" = x; then :; else \
for x in \
$(gsettings_SCHEMAS:.xml=.valid) \
$(gsettings__enum_file) \
; do echo /$$x; done; \
fi; \
if test -f $(srcdir)/po/Makefile.in.in; then \
for x in \
po/Makefile.in.in \
po/Makefile.in \
po/Makefile \
po/POTFILES \
po/stamp-it \
po/.intltool-merge-cache \
"po/*.gmo" \
"po/*.mo" \
po/$(GETTEXT_PACKAGE).pot \
intltool-extract.in \
intltool-merge.in \
intltool-update.in \
; do echo /$$x; done; \
fi; \
if test -f $(srcdir)/configure; then \
for x in \
autom4te.cache \
configure \
config.h \
stamp-h1 \
libtool \
config.lt \
; do echo /$$x; done; \
fi; \
for x in \
.gitignore \
$(GITIGNOREFILES) \
$(CLEANFILES) \
$(PROGRAMS) \
$(check_PROGRAMS) \
$(EXTRA_PROGRAMS) \
$(LTLIBRARIES) \
so_locations \
.libs _libs \
$(MOSTLYCLEANFILES) \
"*.$(OBJEXT)" \
"*.lo" \
$(DISTCLEANFILES) \
$(am__CONFIG_DISTCLEAN_FILES) \
$(CONFIG_CLEAN_FILES) \
TAGS ID GTAGS GRTAGS GSYMS GPATH tags \
"*.tab.c" \
$(MAINTAINERCLEANFILES) \
$(BUILT_SOURCES) \
$(DEPDIR) \
Makefile \
Makefile.in \
"*.orig" \
"*.rej" \
"*.bak" \
"*~" \
".*.sw[nop]" \
".dirstamp" \
; do echo /$$x; done; \
} | \
sed "s@^/`echo "$(srcdir)" | sed 's/\(.\)/[\1]/g'`/@/@" | \
sed 's@/[.]/@/@g' | \
LC_ALL=C sort | uniq > $@.tmp && \
mv $@.tmp $@;
all: $(srcdir)/.gitignore gitignore-recurse-maybe
gitignore-recurse-maybe:
@if test "x$(SUBDIRS)" = "x$(DIST_SUBDIRS)"; then :; else \
$(MAKE) $(AM_MAKEFLAGS) gitignore-recurse; \
fi;
gitignore-recurse:
@for subdir in $(DIST_SUBDIRS); do \
case " $(SUBDIRS) " in \
*" $$subdir "*) :;; \
*) test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) .gitignore gitignore-recurse || echo "Skipping $$subdir");; \
esac; \
done
gitignore: $(srcdir)/.gitignore gitignore-recurse
maintainer-clean: gitignore-clean
gitignore-clean:
-rm -f $(srcdir)/.gitignore
.PHONY: gitignore-clean gitignore gitignore-recurse gitignore-recurse-maybe

1
m4/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
*.m4

24
m4/as-linguas.m4 Normal file
View File

@ -0,0 +1,24 @@
# Set ALL_ALL_LINGUAS based on the .po files present. Optional argument is the
# name of the po directory. $podir/LINGUAS.ignore can be used to ignore a
# subset of the po files.
AC_DEFUN([AS_ALL_LINGUAS],
[
AC_MSG_CHECKING([for linguas])
podir="m4_default([$1],[$srcdir/po])"
linguas=`cd $podir && ls *.po 2>/dev/null | awk 'BEGIN { FS="."; ORS=" " } { print $[]1 }'`
if test -f "$podir/LINGUAS.ignore"; then
ALL_LINGUAS="";
ignore_linguas=`sed -n -e 's/^\s\+\|\s\+$//g' -e '/^#/b' -e '/\S/!b' \
-e 's/\s\+/\n/g' -e p "$podir/LINGUAS.ignore"`;
for lang in $linguas; do
if ! echo "$ignore_linguas" | grep -q "^${lang}$"; then
ALL_LINGUAS="$ALL_LINGUAS $lang";
fi;
done;
else
ALL_LINGUAS="$linguas";
fi;
AC_SUBST([ALL_LINGUAS])
AC_MSG_RESULT($ALL_LINGUAS)
])

View File

@ -0,0 +1,72 @@
# ===========================================================================
# http://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS])
#
# DESCRIPTION
#
# Check whether the given FLAG works with the current language's compiler
# or gives an error. (Warnings, however, are ignored)
#
# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
# success/failure.
#
# If EXTRA-FLAGS is defined, it is added to the current language's default
# flags (e.g. CFLAGS) when the check is done. The check is thus made with
# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to
# force the compiler to issue an error when a bad flag is given.
#
# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG.
#
# LICENSE
#
# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation, either version 3 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 2
AC_DEFUN([AX_CHECK_COMPILE_FLAG],
[AC_PREREQ(2.59)dnl for _AC_LANG_PREFIX
AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl
AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [
ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS
_AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM()],
[AS_VAR_SET(CACHEVAR,[yes])],
[AS_VAR_SET(CACHEVAR,[no])])
_AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags])
AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes],
[m4_default([$2], :)],
[m4_default([$3], :)])
AS_VAR_POPDEF([CACHEVAR])dnl
])dnl AX_CHECK_COMPILE_FLAGS

71
m4/ax_check_link_flag.m4 Normal file
View File

@ -0,0 +1,71 @@
# ===========================================================================
# http://www.gnu.org/software/autoconf-archive/ax_check_link_flag.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_CHECK_LINK_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS])
#
# DESCRIPTION
#
# Check whether the given FLAG works with the linker or gives an error.
# (Warnings, however, are ignored)
#
# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
# success/failure.
#
# If EXTRA-FLAGS is defined, it is added to the linker's default flags
# when the check is done. The check is thus made with the flags: "LDFLAGS
# EXTRA-FLAGS FLAG". This can for example be used to force the linker to
# issue an error when a bad flag is given.
#
# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
# macro in sync with AX_CHECK_{PREPROC,COMPILE}_FLAG.
#
# LICENSE
#
# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation, either version 3 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 2
AC_DEFUN([AX_CHECK_LINK_FLAG],
[AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_ldflags_$4_$1])dnl
AC_CACHE_CHECK([whether the linker accepts $1], CACHEVAR, [
ax_check_save_flags=$LDFLAGS
LDFLAGS="$LDFLAGS $4 $1"
AC_LINK_IFELSE([AC_LANG_PROGRAM()],
[AS_VAR_SET(CACHEVAR,[yes])],
[AS_VAR_SET(CACHEVAR,[no])])
LDFLAGS=$ax_check_save_flags])
AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes],
[m4_default([$2], :)],
[m4_default([$3], :)])
AS_VAR_POPDEF([CACHEVAR])dnl
])dnl AX_CHECK_LINK_FLAGS

26
man/Makefile.am Normal file
View File

@ -0,0 +1,26 @@
man_MANS_DIST = \
fwupdmgr.1
EXTRA_DIST = \
fwupdmgr.sgml \
$(man_MANS_DIST)
man_MANS = \
$(man_MANS_DIST)
fwupdmgr.1: fwupdmgr.sgml
$(AM_V_GEN) \
docbook2man $? > /dev/null
MAINTAINERCLEANFILES = \
manpage.links \
manpage.log \
manpage.refs \
$(man_MANS)
clean-local :
rm -f *~
rm -f *.1
rm -f manpage.*
-include $(top_srcdir)/git.mk

113
man/fwupdmgr.sgml Normal file
View File

@ -0,0 +1,113 @@
<!doctype refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN" [
<!-- Please adjust the date whenever revising the manpage. -->
<!ENTITY date "<date>26 February,2015</date>">
<!ENTITY package "fwupdmgr">
<!ENTITY gnu "<acronym>GNU</acronym>">
<!ENTITY gpl "&gnu; <acronym>GPL</acronym>">
]>
<refentry>
<refentryinfo>
<address>
<email>richard@hughsie.com</email>;
</address>
<author>
<firstname>Richard</firstname>
<surname>Hughes</surname>
</author>
<copyright>
<year>2015</year>
<holder>Richard Hughes</holder>
</copyright>
&date;
</refentryinfo>
<refmeta>
<refentrytitle>fwupdmgr</refentrytitle>
<manvolnum>1</manvolnum>
</refmeta>
<refnamediv>
<refname>&package;</refname>
<refpurpose>fwupd client tool</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>&package;</command>
<arg><option>--verbose</option></arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>DESCRIPTION</title>
<para>
This manual page documents briefly the <command>&package;</command> command.
</para>
<para>
<command>&package;</command> allows an administrator to update firmware.
</para>
</refsect1>
<refsect1>
<title>OPTIONS</title>
<para>
This program follows the usual &gnu; command line syntax,
with long options starting with two dashes (`-'). A summary of
options is included below.
</para>
<variablelist>
<varlistentry>
<term>
<option>--help</option>
</term>
<listitem>
<para>Show summary of options.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>COMMANDS</title>
<para>
This program takes commands with a variable number of arguments.
</para>
<variablelist>
<varlistentry>
<term>
<option>get-devices</option>
</term>
<listitem>
<para>Get the list of hardware that supports firmware updates.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>update-offline</option>
<parameter>guid</parameter>
<parameter>filename</parameter>
</term>
<listitem>
<para>Install the update the next time the computer is rebooted.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>AUTHOR</title>
<para>This manual page was written by Richard Hughes <email>richard@hughsie.com</email>.
</para>
</refsect1>
</refentry>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:2
sgml-indent-data:t
sgml-parent-document:nil
sgml-default-dtd-file:nil
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
-->

10
po/.gitignore vendored Normal file
View File

@ -0,0 +1,10 @@
*.gmo
*.header
.intltool-merge-cache
Makefile.in.in
Makevars.template
POTFILES
Rules-quot
*.sed
*.sin
stamp-it

3
po/POTFILES.in Normal file
View File

@ -0,0 +1,3 @@
policy/org.freedesktop.fwupd.policy.in
src/fu-main.c
src/fu-util.c

25
po/en_GB.po Normal file
View File

@ -0,0 +1,25 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
# Richard Hughes <richard@hughsie.com>, 2015
# Robert Readman <robert_readman@hotmail.com>, 2013
msgid ""
msgstr ""
"Project-Id-Version: fwupd\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2014-11-10 11:04+0000\n"
"PO-Revision-Date: 2014-11-10 11:04+0000\n"
"Last-Translator: Richard Hughes <richard@hughsie.com>\n"
"Language-Team: English (United Kingdom) (http://www.transifex.com/projects/p/colord/language/en_GB/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: en_GB\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. TRANSLATORS: this is a command alias
#, c-format
msgid "Alias to %s"
msgstr "Alias to %s"

12
policy/Makefile.am Normal file
View File

@ -0,0 +1,12 @@
@INTLTOOL_POLICY_RULE@
polkit_policydir = $(datadir)/polkit-1/actions
polkit_policy_in_files = org.freedesktop.fwupd.policy.in
polkit_policy_DATA = $(polkit_policy_in_files:.policy.in=.policy)
#polkit_policy_DATA = \
# org.freedesktop.fwupd.policy
EXTRA_DIST = org.freedesktop.fwupd.policy.in
CLEANFILES = \
org.freedesktop.fwupd.policy
-include $(top_srcdir)/git.mk

View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE policyconfig PUBLIC
"-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
"http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd">
<policyconfig>
<!--
Policy definitions for fwupd actions.
Copyright (c) 2015 Richard Hughes <richard@hughsie.com>
-->
<vendor>System firmware update</vendor>
<vendor_url>https://github.com/hughsie/fwupd</vendor_url>
<icon_name>application-vnd.iccprofile</icon_name>
<action id="org.freedesktop.fwupd.update">
<!-- SECURITY:
- Normal users require admin authentication to update firmware
- This should not be set to 'yes' as unprivileged users could then
update to hostile and unsigned firmware.
-->
<_description>Install system firmware update</_description>
<_message>Authentication is required to update the firmware on this machine</_message>
<icon_name>application-vnd.iccprofile</icon_name>
<defaults>
<allow_any>auth_admin</allow_any>
<allow_inactive>no</allow_inactive>
<allow_active>auth_admin_keep</allow_active>
</defaults>
</action>
</policyconfig>

89
src/Makefile.am Normal file
View File

@ -0,0 +1,89 @@
introspectiondir = $(datadir)/dbus-1/interfaces
dist_introspection_DATA = \
org.freedesktop.fwupd.xml
AM_CPPFLAGS = \
$(PIE_CFLAGS) \
$(GLIB_CFLAGS) \
$(POLKIT_CFLAGS) \
$(GUDEV_CFLAGS) \
-DG_LOG_DOMAIN=\"Fu\" \
-DLIBEXECDIR=\"$(libexecdir)\" \
-DLIBDIR=\"$(libdir)\" \
-DDATADIR=\"$(datadir)\" \
-DSYSCONFDIR=\""$(sysconfdir)"\" \
-DLOCALSTATEDIR=\""$(localstatedir)"\" \
-DVERSION="\"$(VERSION)\"" \
-DDAEMON_USER="\"$(daemon_user)\"" \
-DG_UDEV_API_IS_SUBJECT_TO_CHANGE \
-DLOCALEDIR=\""$(localedir)"\"
bin_PROGRAMS = fwupdmgr
fwupdmgr_SOURCES = \
fu-util.c
fwupdmgr_LDADD = \
$(GLIB_LIBS)
fwupdmgr_LDFLAGS = \
$(PIE_LDFLAGS)
fwupdmgr_CFLAGS = \
$(WARNINGFLAGS_C)
fu-resources.c: fwupd.gresource.xml $(dist_introspection_DATA)
$(AM_V_GEN) \
glib-compile-resources \
--sourcedir=$(srcdir) \
--sourcedir=$(top_builddir)/data \
--target=$@ \
--generate-source \
--c-name fu \
$(srcdir)/fwupd.gresource.xml
fu-resources.h: fwupd.gresource.xml
$(AM_V_GEN) \
glib-compile-resources \
--sourcedir=$(srcdir) \
--sourcedir=$(top_builddir)/data \
--target=$@ \
--generate-header \
--c-name fu \
$(srcdir)/fwupd.gresource.xml
libexec_PROGRAMS = \
fwupd
fwupd_SOURCES = \
fu-cleanup.h \
fu-common.h \
fu-device.c \
fu-device.h \
fu-provider-uefi.c \
fu-provider-uefi.h \
fu-resources.c \
fu-resources.h \
fu-main.c
fwupd_LDADD = \
$(POLKIT_LIBS) \
$(GUDEV_LIBS) \
$(GLIB_LIBS)
fwupd_LDFLAGS = \
$(PIE_LDFLAGS) \
$(RELRO_LDFLAGS)
fwupd_CFLAGS = \
$(WARNINGFLAGS_C)
BUILT_SOURCES = \
fu-resources.c \
fu-resources.h
CLEANFILES = $(BUILT_SOURCES) *.log *.trs
EXTRA_DIST = \
fwupd.gresource.xml
-include $(top_srcdir)/git.mk

91
src/fu-cleanup.h Normal file
View File

@ -0,0 +1,91 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*
* Copyright (C) 2012 Colin Walters <walters@verbum.org>.
* Copyright (C) 2014-2015 Richard Hughes <richard@hughsie.com>
*
* Licensed under the GNU Lesser General Public License Version 2.1
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __FU_CLEANUP_H__
#define __FU_CLEANUP_H__
#include <gio/gio.h>
G_BEGIN_DECLS
#define GS_DEFINE_CLEANUP_FUNCTION(Type, name, func) \
static inline void name (void *v) \
{ \
func (*(Type*)v); \
}
#define GS_DEFINE_CLEANUP_FUNCTION0(Type, name, func) \
static inline void name (void *v) \
{ \
if (*(Type*)v) \
func (*(Type*)v); \
}
#define GS_DEFINE_CLEANUP_FUNCTIONt(Type, name, func) \
static inline void name (void *v) \
{ \
if (*(Type*)v) \
func (*(Type*)v, TRUE); \
}
GS_DEFINE_CLEANUP_FUNCTION0(GArray*, gs_local_array_unref, g_array_unref)
GS_DEFINE_CLEANUP_FUNCTION0(GBytes*, gs_local_bytes_unref, g_bytes_unref)
GS_DEFINE_CLEANUP_FUNCTION0(GChecksum*, gs_local_checksum_free, g_checksum_free)
GS_DEFINE_CLEANUP_FUNCTION0(GDir*, gs_local_dir_close, g_dir_close)
GS_DEFINE_CLEANUP_FUNCTION0(GError*, gs_local_free_error, g_error_free)
GS_DEFINE_CLEANUP_FUNCTION0(GHashTable*, gs_local_hashtable_unref, g_hash_table_unref)
GS_DEFINE_CLEANUP_FUNCTION0(GKeyFile*, gs_local_keyfile_unref, g_key_file_unref)
GS_DEFINE_CLEANUP_FUNCTION0(GMarkupParseContext*, gs_local_markup_parse_context_unref, g_markup_parse_context_unref)
GS_DEFINE_CLEANUP_FUNCTION0(GObject*, gs_local_obj_unref, g_object_unref)
GS_DEFINE_CLEANUP_FUNCTION0(GPtrArray*, gs_local_ptrarray_unref, g_ptr_array_unref)
GS_DEFINE_CLEANUP_FUNCTION0(GTimer*, gs_local_destroy_timer, g_timer_destroy)
GS_DEFINE_CLEANUP_FUNCTION0(GVariantBuilder*, gs_local_variant_builder_unref, g_variant_builder_unref)
GS_DEFINE_CLEANUP_FUNCTION0(GVariant*, gs_local_variant_unref, g_variant_unref)
GS_DEFINE_CLEANUP_FUNCTION0(GVariantIter*, gs_local_variant_iter_free, g_variant_iter_free)
GS_DEFINE_CLEANUP_FUNCTIONt(GString*, gs_local_free_string, g_string_free)
GS_DEFINE_CLEANUP_FUNCTION(char**, gs_local_strfreev, g_strfreev)
GS_DEFINE_CLEANUP_FUNCTION(GList*, gs_local_free_list, g_list_free)
GS_DEFINE_CLEANUP_FUNCTION(void*, gs_local_free, g_free)
#define _cleanup_dir_close_ __attribute__ ((cleanup(gs_local_dir_close)))
#define _cleanup_timer_destroy_ __attribute__ ((cleanup(gs_local_destroy_timer)))
#define _cleanup_free_ __attribute__ ((cleanup(gs_local_free)))
#define _cleanup_checksum_free_ __attribute__ ((cleanup(gs_local_checksum_free)))
#define _cleanup_error_free_ __attribute__ ((cleanup(gs_local_free_error)))
#define _cleanup_list_free_ __attribute__ ((cleanup(gs_local_free_list)))
#define _cleanup_string_free_ __attribute__ ((cleanup(gs_local_free_string)))
#define _cleanup_strv_free_ __attribute__ ((cleanup(gs_local_strfreev)))
#define _cleanup_variant_iter_free_ __attribute__ ((cleanup(gs_local_variant_iter_free)))
#define _cleanup_array_unref_ __attribute__ ((cleanup(gs_local_array_unref)))
#define _cleanup_bytes_unref_ __attribute__ ((cleanup(gs_local_bytes_unref)))
#define _cleanup_hashtable_unref_ __attribute__ ((cleanup(gs_local_hashtable_unref)))
#define _cleanup_keyfile_unref_ __attribute__ ((cleanup(gs_local_keyfile_unref)))
#define _cleanup_markup_parse_context_unref_ __attribute__ ((cleanup(gs_local_markup_parse_context_unref)))
#define _cleanup_object_unref_ __attribute__ ((cleanup(gs_local_obj_unref)))
#define _cleanup_ptrarray_unref_ __attribute__ ((cleanup(gs_local_ptrarray_unref)))
#define _cleanup_variant_unref_ __attribute__ ((cleanup(gs_local_variant_unref)))
G_END_DECLS
#endif

29
src/fu-common.h Normal file
View File

@ -0,0 +1,29 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*
* Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
*
* Licensed under the GNU General Public License Version 2
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef __FU_COMMON_H
#define __FU_COMMON_H
#define FWUPD_DBUS_PATH "/"
#define FWUPD_DBUS_SERVICE "org.freedesktop.fwupd"
#define FWUPD_DBUS_INTERFACE "org.freedesktop.fwupd"
#endif /* __FU_COMMON_H */

173
src/fu-device.c Normal file
View File

@ -0,0 +1,173 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*
* Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
*
* Licensed under the GNU General Public License Version 2
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "config.h"
#include <glib-object.h>
#include <gio/gio.h>
#include "fu-cleanup.h"
#include "fu-common.h"
#include "fu-device.h"
static void fu_device_finalize (GObject *object);
#define FU_DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), FU_TYPE_DEVICE, FuDevicePrivate))
/**
* FuDevicePrivate:
*
* Private #FuDevice data
**/
struct _FuDevicePrivate
{
gchar *id;
};
enum {
SIGNAL_LAST
};
enum {
PROP_0,
PROP_ID,
PROP_LAST
};
G_DEFINE_TYPE (FuDevice, fu_device, G_TYPE_OBJECT)
/**
* fu_device_get_id:
**/
const gchar *
fu_device_get_id (FuDevice *device)
{
g_return_val_if_fail (FU_IS_DEVICE (device), NULL);
return device->priv->id;
}
/**
* fu_device_set_id:
**/
void
fu_device_set_id (FuDevice *device, const gchar *id)
{
g_return_if_fail (FU_IS_DEVICE (device));
g_free (device->priv->id);
device->priv->id = g_strdup (id);
}
/**
* fu_device_get_property:
**/
static void
fu_device_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
{
FuDevice *device = FU_DEVICE (object);
FuDevicePrivate *priv = device->priv;
switch (prop_id) {
case PROP_ID:
g_value_set_string (value, priv->id);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
/**
* fu_device_set_property:
**/
static void
fu_device_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
{
FuDevice *device = FU_DEVICE (object);
FuDevicePrivate *priv = device->priv;
switch (prop_id) {
case PROP_ID:
g_free (priv->id);
priv->id = g_strdup (g_value_get_string (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
/**
* fu_device_class_init:
**/
static void
fu_device_class_init (FuDeviceClass *klass)
{
GParamSpec *pspec;
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = fu_device_finalize;
object_class->get_property = fu_device_get_property;
object_class->set_property = fu_device_set_property;
/**
* FuDevice:id:
*/
pspec = g_param_spec_string ("id", NULL, NULL,
NULL,
G_PARAM_READWRITE);
g_object_class_install_property (object_class, PROP_ID, pspec);
g_type_class_add_private (klass, sizeof (FuDevicePrivate));
}
/**
* fu_device_init:
**/
static void
fu_device_init (FuDevice *device)
{
device->priv = FU_DEVICE_GET_PRIVATE (device);
}
/**
* fu_device_finalize:
**/
static void
fu_device_finalize (GObject *object)
{
FuDevice *device = FU_DEVICE (object);
FuDevicePrivate *priv = device->priv;
g_free (priv->id);
G_OBJECT_CLASS (fu_device_parent_class)->finalize (object);
}
/**
* fu_device_new:
**/
FuDevice *
fu_device_new (void)
{
FuDevice *device;
device = g_object_new (FU_TYPE_DEVICE, NULL);
return FU_DEVICE (device);
}

63
src/fu-device.h Normal file
View File

@ -0,0 +1,63 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*
* Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
*
* Licensed under the GNU General Public License Version 2
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef __FU_DEVICE_H
#define __FU_DEVICE_H
#include <glib-object.h>
G_BEGIN_DECLS
#define FU_TYPE_DEVICE (fu_device_get_type ())
#define FU_DEVICE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), FU_TYPE_DEVICE, FuDevice))
#define FU_DEVICE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), FU_TYPE_DEVICE, FuDeviceClass))
#define FU_IS_DEVICE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), FU_TYPE_DEVICE))
#define FU_IS_DEVICE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), FU_TYPE_DEVICE))
#define FU_DEVICE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), FU_TYPE_DEVICE, FuDeviceClass))
#define FU_DEVICE_ERROR fu_device_error_quark()
typedef struct _FuDevicePrivate FuDevicePrivate;
typedef struct _FuDevice FuDevice;
typedef struct _FuDeviceClass FuDeviceClass;
struct _FuDevice
{
GObject parent;
FuDevicePrivate *priv;
};
struct _FuDeviceClass
{
GObjectClass parent_class;
};
GType fu_device_get_type (void);
FuDevice *fu_device_new (void);
/* accessors */
const gchar *fu_device_get_id (FuDevice *device);
void fu_device_set_id (FuDevice *device,
const gchar *id);
G_END_DECLS
#endif /* __FU_DEVICE_H */

327
src/fu-main.c Normal file
View File

@ -0,0 +1,327 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*
* Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
*
* Licensed under the GNU General Public License Version 2
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "config.h"
#include <stdlib.h>
#include <gio/gio.h>
#include <gio/gunixfdlist.h>
#include <glib/gi18n.h>
#include <locale.h>
#include "fu-cleanup.h"
#include "fu-common.h"
#include "fu-device.h"
#include "fu-provider-uefi.h"
#include "fu-resources.h"
#define FU_ERROR 1
#define FU_ERROR_INTERNAL 0
typedef struct {
GDBusConnection *connection;
GDBusNodeInfo *introspection_daemon;
GMainLoop *loop;
GPtrArray *devices;
FuProviderUefi *provider_uefi;
} FuMainPrivate;
/**
* fu_main_get_device_list_as_strv:
**/
static gchar **
fu_main_get_device_list_as_strv (FuMainPrivate *priv)
{
gchar **val;
guint i;
FuDevice *dev_tmp;
val = g_new0 (gchar *, priv->devices->len + 1);
for (i = 0; i < priv->devices->len; i++) {
dev_tmp = g_ptr_array_index (priv->devices, i);
val[i] = g_strdup (fu_device_get_id (dev_tmp));
}
return val;
}
/**
* fu_main_daemon_method_call:
**/
static void
fu_main_daemon_method_call (GDBusConnection *connection, const gchar *sender,
const gchar *object_path, const gchar *interface_name,
const gchar *method_name, GVariant *parameters,
GDBusMethodInvocation *invocation, gpointer user_data)
{
FuMainPrivate *priv = (FuMainPrivate *) user_data;
GVariant *val;
/* return 'as' */
if (g_strcmp0 (method_name, "GetDevices") == 0) {
_cleanup_strv_free_ gchar **devices = NULL;
devices = fu_main_get_device_list_as_strv (priv);
val = g_variant_new ("(^as)", devices);
g_dbus_method_invocation_return_value (invocation, val);
return;
}
/* we suck */
g_dbus_method_invocation_return_error (invocation,
FU_ERROR,
FU_ERROR_INTERNAL,
"no such method %s",
method_name);
}
/**
* fu_main_daemon_get_property:
**/
static GVariant *
fu_main_daemon_get_property (GDBusConnection *connection_, const gchar *sender,
const gchar *object_path, const gchar *interface_name,
const gchar *property_name, GError **error,
gpointer user_data)
{
if (g_strcmp0 (property_name, "DaemonVersion") == 0)
return g_variant_new_string (VERSION);
/* return an error */
g_set_error (error,
FU_ERROR,
FU_ERROR_INTERNAL,
"failed to get daemon property %s",
property_name);
return NULL;
}
/**
* fu_main_on_bus_acquired_cb:
**/
static void
fu_main_on_bus_acquired_cb (GDBusConnection *connection,
const gchar *name,
gpointer user_data)
{
FuMainPrivate *priv = (FuMainPrivate *) user_data;
guint registration_id;
static const GDBusInterfaceVTable interface_vtable = {
fu_main_daemon_method_call,
fu_main_daemon_get_property,
NULL
};
priv->connection = g_object_ref (connection);
registration_id = g_dbus_connection_register_object (connection,
FWUPD_DBUS_PATH,
priv->introspection_daemon->interfaces[0],
&interface_vtable,
priv, /* user_data */
NULL, /* user_data_free_func */
NULL); /* GError** */
g_assert (registration_id > 0);
}
/**
* fu_main_on_name_acquired_cb:
**/
static void
fu_main_on_name_acquired_cb (GDBusConnection *connection,
const gchar *name,
gpointer user_data)
{
FuMainPrivate *priv = (FuMainPrivate *) user_data;
fu_provider_uefi_coldplug (priv->provider_uefi);
g_debug ("FuMain: acquired name: %s", name);
}
/**
* fu_main_on_name_lost_cb:
**/
static void
fu_main_on_name_lost_cb (GDBusConnection *connection,
const gchar *name,
gpointer user_data)
{
FuMainPrivate *priv = (FuMainPrivate *) user_data;
g_debug ("FuMain: lost name: %s", name);
g_main_loop_quit (priv->loop);
}
/**
* fu_main_timed_exit_cb:
**/
static gboolean
fu_main_timed_exit_cb (gpointer user_data)
{
GMainLoop *loop = (GMainLoop *) user_data;
g_main_loop_quit (loop);
return G_SOURCE_REMOVE;
}
/**
* fu_main_load_introspection:
**/
static GDBusNodeInfo *
fu_main_load_introspection (const gchar *filename, GError **error)
{
_cleanup_bytes_unref_ GBytes *data = NULL;
_cleanup_free_ gchar *path = NULL;
/* lookup data */
path = g_build_filename ("/org/freedesktop/fwupd", filename, NULL);
data = g_resource_lookup_data (fu_get_resource (),
path,
G_RESOURCE_LOOKUP_FLAGS_NONE,
error);
if (data == NULL)
return NULL;
/* build introspection from XML */
return g_dbus_node_info_new_for_xml (g_bytes_get_data (data, NULL), error);
}
/**
* cd_main_provider_device_added_cb:
**/
static void
cd_main_provider_device_added_cb (FuProviderUefi *provider_uefi,
FuDevice *device,
gpointer user_data)
{
FuMainPrivate *priv = (FuMainPrivate *) user_data;
g_ptr_array_add (priv->devices, g_object_ref (device));
}
/**
* cd_main_provider_device_removed_cb:
**/
static void
cd_main_provider_device_removed_cb (FuProviderUefi *provider_uefi,
FuDevice *device,
gpointer user_data)
{
FuMainPrivate *priv = (FuMainPrivate *) user_data;
g_ptr_array_remove (priv->devices, g_object_ref (device));
}
/**
* main:
**/
int
main (int argc, char *argv[])
{
FuMainPrivate *priv = NULL;
gboolean immediate_exit = FALSE;
gboolean ret;
gboolean timed_exit = FALSE;
GOptionContext *context;
guint owner_id = 0;
guint retval = 1;
const GOptionEntry options[] = {
{ "timed-exit", '\0', 0, G_OPTION_ARG_NONE, &timed_exit,
/* TRANSLATORS: exit after we've started up, used for user profiling */
_("Exit after a small delay"), NULL },
{ "immediate-exit", '\0', 0, G_OPTION_ARG_NONE, &immediate_exit,
/* TRANSLATORS: exit straight away, used for automatic profiling */
_("Exit after the engine has loaded"), NULL },
{ NULL}
};
_cleanup_error_free_ GError *error = NULL;
setlocale (LC_ALL, "");
bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
textdomain (GETTEXT_PACKAGE);
/* TRANSLATORS: program name */
g_set_application_name (_("Firmware Update"));
context = g_option_context_new (NULL);
g_option_context_add_main_entries (context, options, NULL);
g_option_context_set_summary (context, _("Firmware Update D-Bus Service"));
ret = g_option_context_parse (context, &argc, &argv, &error);
if (!ret) {
g_warning ("FuMain: failed to parse command line arguments: %s",
error->message);
goto out;
}
/* create new objects */
priv = g_new0 (FuMainPrivate, 1);
priv->devices = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
priv->loop = g_main_loop_new (NULL, FALSE);
priv->provider_uefi = fu_provider_uefi_new ();
g_signal_connect (priv->provider_uefi, "device-added",
G_CALLBACK (cd_main_provider_device_added_cb),
priv);
g_signal_connect (priv->provider_uefi, "device-removed",
G_CALLBACK (cd_main_provider_device_removed_cb),
priv);
/* load introspection from file */
priv->introspection_daemon = fu_main_load_introspection (FWUPD_DBUS_INTERFACE ".xml",
&error);
if (priv->introspection_daemon == NULL) {
g_warning ("FuMain: failed to load daemon introspection: %s",
error->message);
goto out;
}
/* own the object */
owner_id = g_bus_own_name (G_BUS_TYPE_SYSTEM,
FWUPD_DBUS_SERVICE,
G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
G_BUS_NAME_OWNER_FLAGS_REPLACE,
fu_main_on_bus_acquired_cb,
fu_main_on_name_acquired_cb,
fu_main_on_name_lost_cb,
priv, NULL);
/* Only timeout and close the mainloop if we have specified it
* on the command line */
if (immediate_exit)
g_idle_add (fu_main_timed_exit_cb, priv->loop);
else if (timed_exit)
g_timeout_add_seconds (5, fu_main_timed_exit_cb, priv->loop);
/* wait */
g_info ("Daemon ready for requests");
g_main_loop_run (priv->loop);
/* success */
retval = 0;
out:
g_option_context_free (context);
if (owner_id > 0)
g_bus_unown_name (owner_id);
if (priv != NULL) {
if (priv->loop != NULL)
g_main_loop_unref (priv->loop);
if (priv->connection != NULL)
g_object_unref (priv->connection);
if (priv->introspection_daemon != NULL)
g_dbus_node_info_unref (priv->introspection_daemon);
g_ptr_array_unref (priv->devices);
g_free (priv);
}
return retval;
}

148
src/fu-provider-uefi.c Normal file
View File

@ -0,0 +1,148 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*
* Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
*
* Licensed under the GNU General Public License Version 2
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "config.h"
#include <glib-object.h>
#include <gio/gio.h>
#include "fu-cleanup.h"
#include "fu-device.h"
#include "fu-provider-uefi.h"
static void fu_provider_uefi_finalize (GObject *object);
#define FU_PROVIDER_UEFI_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), FU_TYPE_PROVIDER_UEFI, FuProviderUefiPrivate))
/**
* FuProviderUefiPrivate:
**/
struct _FuProviderUefiPrivate
{
GPtrArray *array_devices;
};
enum {
SIGNAL_SENSOR_ADDED,
SIGNAL_SENSOR_REMOVED,
SIGNAL_LAST
};
static guint signals[SIGNAL_LAST] = { 0 };
G_DEFINE_TYPE (FuProviderUefi, fu_provider_uefi, G_TYPE_OBJECT)
/**
* fu_provider_uefi_get_by_id:
**/
static FuDevice *
fu_provider_uefi_get_by_id (FuProviderUefi *provider_uefi,
const gchar *device_id)
{
FuProviderUefiPrivate *priv = provider_uefi->priv;
FuDevice *device = NULL;
FuDevice *device_tmp;
guint i;
for (i = 0; i < priv->array_devices->len; i++) {
device_tmp = g_ptr_array_index (priv->array_devices, i);
if (g_strcmp0 (fu_device_get_id (device_tmp), device_id) == 0) {
device = g_object_ref (device_tmp);
break;
}
}
return device;
}
/**
* fu_provider_uefi_coldplug:
**/
void
fu_provider_uefi_coldplug (FuProviderUefi *provider_uefi)
{
_cleanup_object_unref_ FuDevice *dev = NULL;
//FIXME
g_debug ("Adding fake UEFI device");
dev = fu_device_new ();
fu_device_set_id (dev, "819b858e-c52c-402f-80e1-5b311b6c1959");
g_signal_emit (provider_uefi, signals[SIGNAL_SENSOR_ADDED], 0, dev);
}
/**
* fu_provider_uefi_class_init:
**/
static void
fu_provider_uefi_class_init (FuProviderUefiClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = fu_provider_uefi_finalize;
signals[SIGNAL_SENSOR_ADDED] =
g_signal_new ("device-added",
G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (FuProviderUefiClass, device_added),
NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1, FU_TYPE_DEVICE);
signals[SIGNAL_SENSOR_REMOVED] =
g_signal_new ("device-removed",
G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (FuProviderUefiClass, device_removed),
NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1, FU_TYPE_DEVICE);
g_type_class_add_private (klass, sizeof (FuProviderUefiPrivate));
}
/**
* fu_provider_uefi_init:
**/
static void
fu_provider_uefi_init (FuProviderUefi *provider_uefi)
{
provider_uefi->priv = FU_PROVIDER_UEFI_GET_PRIVATE (provider_uefi);
provider_uefi->priv->array_devices = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
}
/**
* fu_provider_uefi_finalize:
**/
static void
fu_provider_uefi_finalize (GObject *object)
{
FuProviderUefi *provider_uefi = FU_PROVIDER_UEFI (object);
FuProviderUefiPrivate *priv = provider_uefi->priv;
g_ptr_array_unref (priv->array_devices);
G_OBJECT_CLASS (fu_provider_uefi_parent_class)->finalize (object);
}
/**
* fu_provider_uefi_new:
**/
FuProviderUefi *
fu_provider_uefi_new (void)
{
FuProviderUefi *provider_uefi;
provider_uefi = g_object_new (FU_TYPE_PROVIDER_UEFI, NULL);
return FU_PROVIDER_UEFI (provider_uefi);
}

65
src/fu-provider-uefi.h Normal file
View File

@ -0,0 +1,65 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*
* Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
*
* Licensed under the GNU General Public License Version 2
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef __FU_PROVIDER_UEFI_H
#define __FU_PROVIDER_UEFI_H
#include <glib-object.h>
#include "fu-device.h"
#include "fu-provider-uefi.h"
G_BEGIN_DECLS
#define FU_TYPE_PROVIDER_UEFI (fu_provider_uefi_get_type ())
#define FU_PROVIDER_UEFI(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), FU_TYPE_PROVIDER_UEFI, FuProviderUefi))
#define FU_PROVIDER_UEFI_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), FU_TYPE_PROVIDER_UEFI, FuProviderUefiClass))
#define FU_IS_PROVIDER_UEFI(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), FU_TYPE_PROVIDER_UEFI))
#define FU_IS_PROVIDER_UEFI_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), FU_TYPE_PROVIDER_UEFI))
#define FU_PROVIDER_UEFI_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), FU_TYPE_PROVIDER_UEFI, FuProviderUefiClass))
typedef struct _FuProviderUefiPrivate FuProviderUefiPrivate;
typedef struct _FuProviderUefi FuProviderUefi;
typedef struct _FuProviderUefiClass FuProviderUefiClass;
struct _FuProviderUefi
{
GObject parent;
FuProviderUefiPrivate *priv;
};
struct _FuProviderUefiClass
{
GObjectClass parent_class;
void (* device_added) (FuProviderUefi *provider_uefi,
FuDevice *device);
void (* device_removed) (FuProviderUefi *provider_uefi,
FuDevice *device);
};
GType fu_provider_uefi_get_type (void);
FuProviderUefi *fu_provider_uefi_new (void);
void fu_provider_uefi_coldplug (FuProviderUefi *provider_uefi);
G_END_DECLS
#endif /* __FU_PROVIDER_UEFI_H */

345
src/fu-util.c Normal file
View File

@ -0,0 +1,345 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*
* Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
*
* Licensed under the GNU General Public License Version 2
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "config.h"
#include <glib/gi18n.h>
#include <gio/gio.h>
#include <locale.h>
#include <stdlib.h>
#include <stdio.h>
#include "fu-cleanup.h"
#include "fu-common.h"
#define FU_ERROR 1
#define FU_ERROR_INVALID_ARGUMENTS 0
#define FU_ERROR_NO_SUCH_CMD 1
typedef struct {
GOptionContext *context;
GPtrArray *cmd_array;
} FuUtilPrivate;
typedef gboolean (*FuUtilPrivateCb) (FuUtilPrivate *util,
gchar **values,
GError **error);
typedef struct {
gchar *name;
gchar *arguments;
gchar *description;
FuUtilPrivateCb callback;
} FuUtilItem;
/**
* fu_util_item_free:
**/
static void
fu_util_item_free (FuUtilItem *item)
{
g_free (item->name);
g_free (item->arguments);
g_free (item->description);
g_free (item);
}
/*
* fu_sort_command_name_cb:
*/
static gint
fu_sort_command_name_cb (FuUtilItem **item1, FuUtilItem **item2)
{
return g_strcmp0 ((*item1)->name, (*item2)->name);
}
/**
* fu_util_add:
**/
static void
fu_util_add (GPtrArray *array,
const gchar *name,
const gchar *arguments,
const gchar *description,
FuUtilPrivateCb callback)
{
guint i;
FuUtilItem *item;
_cleanup_strv_free_ gchar **names = NULL;
g_return_if_fail (name != NULL);
g_return_if_fail (description != NULL);
g_return_if_fail (callback != NULL);
/* add each one */
names = g_strsplit (name, ",", -1);
for (i = 0; names[i] != NULL; i++) {
item = g_new0 (FuUtilItem, 1);
item->name = g_strdup (names[i]);
if (i == 0) {
item->description = g_strdup (description);
} else {
/* TRANSLATORS: this is a command alias */
item->description = g_strdup_printf (_("Alias to %s"),
names[0]);
}
item->arguments = g_strdup (arguments);
item->callback = callback;
g_ptr_array_add (array, item);
}
}
/**
* fu_util_get_descriptions:
**/
static gchar *
fu_util_get_descriptions (GPtrArray *array)
{
guint i;
guint j;
guint len;
const guint max_len = 35;
FuUtilItem *item;
GString *string;
/* print each command */
string = g_string_new ("");
for (i = 0; i < array->len; i++) {
item = g_ptr_array_index (array, i);
g_string_append (string, " ");
g_string_append (string, item->name);
len = strlen (item->name) + 2;
if (item->arguments != NULL) {
g_string_append (string, " ");
g_string_append (string, item->arguments);
len += strlen (item->arguments) + 1;
}
if (len < max_len) {
for (j = len; j < max_len + 1; j++)
g_string_append_c (string, ' ');
g_string_append (string, item->description);
g_string_append_c (string, '\n');
} else {
g_string_append_c (string, '\n');
for (j = 0; j < max_len + 1; j++)
g_string_append_c (string, ' ');
g_string_append (string, item->description);
g_string_append_c (string, '\n');
}
}
/* remove trailing newline */
if (string->len > 0)
g_string_set_size (string, string->len - 1);
return g_string_free (string, FALSE);
}
/**
* fu_util_run:
**/
static gboolean
fu_util_run (FuUtilPrivate *priv, const gchar *command, gchar **values, GError **error)
{
guint i;
FuUtilItem *item;
_cleanup_string_free_ GString *string = NULL;
/* find command */
for (i = 0; i < priv->cmd_array->len; i++) {
item = g_ptr_array_index (priv->cmd_array, i);
if (g_strcmp0 (item->name, command) == 0)
return item->callback (priv, values, error);
}
/* not found */
string = g_string_new ("");
/* TRANSLATORS: error message */
g_string_append_printf (string, "%s\n",
_("Command not found, valid commands are:"));
for (i = 0; i < priv->cmd_array->len; i++) {
item = g_ptr_array_index (priv->cmd_array, i);
g_string_append_printf (string, " * %s %s\n",
item->name,
item->arguments ? item->arguments : "");
}
g_set_error_literal (error, FU_ERROR, FU_ERROR_NO_SUCH_CMD, string->str);
return FALSE;
}
/**
* fu_util_get_devices:
**/
static gboolean
fu_util_get_devices (FuUtilPrivate *priv, gchar **values, GError **error)
{
_cleanup_object_unref_ GDBusConnection *conn = NULL;
_cleanup_object_unref_ GDBusProxy *proxy = NULL;
_cleanup_variant_unref_ GVariant *val = NULL;
const gchar **guids = NULL;
guint i;
conn = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, error);
if (conn == NULL)
return FALSE;
proxy = g_dbus_proxy_new_sync (conn,
G_DBUS_PROXY_FLAGS_NONE,
NULL,
FWUPD_DBUS_SERVICE,
FWUPD_DBUS_PATH,
FWUPD_DBUS_INTERFACE,
NULL,
error);
if (proxy == NULL)
return FALSE;
val = g_dbus_proxy_call_sync (proxy,
"GetDevices",
NULL,
G_DBUS_CALL_FLAGS_NONE,
-1,
NULL,
error);
if (val == NULL)
return FALSE;
g_variant_get (val, "(^a&s)", &guids);
g_assert (guids != NULL);
if (guids[0] == NULL)
g_print ("No hardware detected with firmware update capaility\n");
for (i = 0; guids[i] != NULL; i++)
g_print ("%i: %s\n", i, guids[i]);
return TRUE;
}
/**
* fu_util_update_offline:
**/
static gboolean
fu_util_update_offline (FuUtilPrivate *priv, gchar **values, GError **error)
{
//FIXME
return TRUE;
}
/**
* fu_util_ignore_cb:
**/
static void
fu_util_ignore_cb (const gchar *log_domain, GLogLevelFlags log_level,
const gchar *message, gpointer user_data)
{
}
/**
* main:
**/
int
main (int argc, char *argv[])
{
FuUtilPrivate *priv;
gboolean ret;
gboolean verbose = FALSE;
guint retval = 1;
_cleanup_error_free_ GError *error = NULL;
_cleanup_free_ gchar *cmd_descriptions = NULL;
const GOptionEntry options[] = {
{ "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose,
/* TRANSLATORS: command line option */
_("Show extra debugging information"), NULL },
{ NULL}
};
setlocale (LC_ALL, "");
bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
textdomain (GETTEXT_PACKAGE);
/* create helper object */
priv = g_new0 (FuUtilPrivate, 1);
/* add commands */
priv->cmd_array = g_ptr_array_new_with_free_func ((GDestroyNotify) fu_util_item_free);
fu_util_add (priv->cmd_array,
"get-devices",
NULL,
/* TRANSLATORS: command description */
_("Get all devices that support firmware updates"),
fu_util_get_devices);
fu_util_add (priv->cmd_array,
"update-offline",
NULL,
/* TRANSLATORS: command description */
_("Install the update the next time the computer is rebooted"),
fu_util_update_offline);
/* sort by command name */
g_ptr_array_sort (priv->cmd_array,
(GCompareFunc) fu_sort_command_name_cb);
/* get a list of the commands */
priv->context = g_option_context_new (NULL);
cmd_descriptions = fu_util_get_descriptions (priv->cmd_array);
g_option_context_set_summary (priv->context, cmd_descriptions);
/* TRANSLATORS: program name */
g_set_application_name (_("Firmware Update"));
g_option_context_add_main_entries (priv->context, options, NULL);
ret = g_option_context_parse (priv->context, &argc, &argv, &error);
if (!ret) {
/* TRANSLATORS: the user didn't read the man page */
g_print ("%s: %s\n", _("Failed to parse arguments"),
error->message);
goto out;
}
/* set verbose? */
if (verbose) {
g_setenv ("FWUPD_VERBOSE", "1", FALSE);
} else {
g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG,
fu_util_ignore_cb, NULL);
}
/* run the specified command */
ret = fu_util_run (priv, argv[1], (gchar**) &argv[2], &error);
if (!ret) {
if (g_error_matches (error, FU_ERROR, FU_ERROR_NO_SUCH_CMD)) {
_cleanup_free_ gchar *tmp = NULL;
tmp = g_option_context_get_help (priv->context, TRUE, NULL);
g_print ("%s", tmp);
} else {
g_print ("%s\n", error->message);
}
goto out;
}
/* success */
retval = 0;
out:
if (priv != NULL) {
if (priv->cmd_array != NULL)
g_ptr_array_unref (priv->cmd_array);
g_option_context_free (priv->context);
g_free (priv);
}
return retval;
}

6
src/fwupd.gresource.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/org/freedesktop/fwupd">
<file preprocess="xml-stripblanks" compressed="true">org.freedesktop.fwupd.xml</file>
</gresource>
</gresources>

View File

@ -0,0 +1,84 @@
<!DOCTYPE node PUBLIC
"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node name="/" xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
<interface name='org.freedesktop.fwupd'>
<doc:doc>
<doc:description>
<doc:para>
The interface used for quering firmware for the system.
</doc:para>
</doc:description>
</doc:doc>
<!--***********************************************************-->
<property name='DaemonVersion' type='s' access='read'>
<doc:doc>
<doc:description>
<doc:para>
The daemon version.
</doc:para>
</doc:description>
</doc:doc>
</property>
<!--***********************************************************-->
<method name='GetDevices'>
<doc:doc>
<doc:description>
<doc:para>
Gets a list of all the devices that support UEFI firmware upgrading.
</doc:para>
</doc:description>
</doc:doc>
<arg type='as' name='devices' direction='out'>
<doc:doc>
<doc:summary>
<doc:para>An array of GUIDs.</doc:para>
</doc:summary>
</doc:doc>
</arg>
</method>
<!--***********************************************************-->
<method name='UpdateOffline'>
<doc:doc>
<doc:description>
<doc:para>
Schedules an update to be done offline.
</doc:para>
</doc:description>
</doc:doc>
<arg type='s' name='guid' direction='in'>
<doc:doc>
<doc:summary>
<doc:para>A GUID of the hardware to update.</doc:para>
</doc:summary>
</doc:doc>
</arg>
<arg type='h' name='handle' direction='in'>
<doc:doc>
<doc:summary>
<doc:para>
An index into the array of file descriptors that may have
been sent with the DBus message.
</doc:para>
</doc:summary>
</doc:doc>
</arg>
</method>
<!--***********************************************************-->
<signal name='Changed'>
<doc:doc>
<doc:description>
<doc:para>
Some value on the interface or the number of devices or
profiles has changed.
</doc:para>
</doc:description>
</doc:doc>
</signal>
</interface>
</node>