summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Zeuthen <davidz@redhat.com>2010-09-28 12:53:15 -0400
committerDavid Zeuthen <davidz@redhat.com>2010-09-28 12:53:15 -0400
commit82b56eba87ff5797d5589f9e4448502f32ea0eed (patch)
tree632036d23baa4d86329caae3e3e78a5cf71befe7
Initial commit
Signed-off-by: David Zeuthen <davidz@redhat.com>
-rw-r--r--Makefile.am2
-rwxr-xr-xautogen.sh101
-rw-r--r--configure.ac124
-rw-r--r--doc/Makefile.am86
-rw-r--r--doc/stc-docs.xml38
-rw-r--r--doc/stc-sections.txt48
-rw-r--r--doc/stc.types2
-rw-r--r--doc/stc.xml43
-rw-r--r--stc/Makefile.am129
-rw-r--r--stc/stc-1.pc.in11
-rw-r--r--stc/stc-bash-completion.sh33
-rw-r--r--stc/stc.c516
-rw-r--r--stc/stc.conf20
-rw-r--r--stc/stc.h39
-rw-r--r--stc/stcenums.h61
-rw-r--r--stc/stcenumtypes.c.template40
-rw-r--r--stc/stcenumtypes.h.template24
-rw-r--r--stc/stcerror.c39
-rw-r--r--stc/stcerror.h47
-rw-r--r--stc/stcitem.c162
-rw-r--r--stc/stcitem.h50
-rw-r--r--stc/stcmonitor.c198
-rw-r--r--stc/stcmonitor.h47
-rw-r--r--stc/stctypes.h43
-rw-r--r--stc/test.c57
25 files changed, 1960 insertions, 0 deletions
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..d203f89
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,2 @@
+
+SUBDIRS = stc doc
diff --git a/autogen.sh b/autogen.sh
new file mode 100755
index 0000000..77ae75e
--- /dev/null
+++ b/autogen.sh
@@ -0,0 +1,101 @@
+#!/bin/sh
+# Run this to generate all the initial makefiles, etc.
+
+set -e
+set -x
+
+srcdir=`dirname $0`
+test -z "$srcdir" && srcdir=.
+
+DIE=0
+
+(test -f $srcdir/configure.ac) || {
+ echo -n "**Error**: Directory $srcdir does not look like the"
+ echo " top-level package directory"
+ exit 1
+}
+
+(gtkdocize --version) < /dev/null > /dev/null 2>&1 || {
+ echo
+ echo "You must have gtk-doc installed to compile $PROJECT."
+ echo "Install the appropriate package for your distribution,"
+ echo "or get the source tarball at ftp://ftp.gnome.org/pub/GNOME/sources
+/gtk-doc/"
+ DIE=1
+}
+
+(autoconf --version) < /dev/null > /dev/null 2>&1 || {
+ echo
+ echo "**Error**: You must have autoconf installed."
+ echo "Download the appropriate package for your distribution,"
+ echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
+ DIE=1
+}
+
+(grep "^AM_PROG_LIBTOOL" $srcdir/configure.ac >/dev/null) && {
+ (libtool --version) < /dev/null > /dev/null 2>&1 || {
+ echo
+ echo "**Error**: You must have libtool installed."
+ echo "You can get it from: ftp://ftp.gnu.org/pub/gnu/"
+ DIE=1
+ }
+}
+
+(automake --version) < /dev/null > /dev/null 2>&1 || {
+ echo
+ echo "**Error**: You must have automake installed."
+ echo "You can get it from: ftp://ftp.gnu.org/pub/gnu/"
+ DIE=1
+ NO_AUTOMAKE=yes
+}
+
+
+# if no automake, don't bother testing for aclocal
+test -n "$NO_AUTOMAKE" || (aclocal --version) < /dev/null > /dev/null 2>&1 || {
+ echo
+ echo "**Error**: Missing aclocal. The version of automake"
+ echo "installed doesn't appear recent enough."
+ echo "You can get automake from ftp://ftp.gnu.org/pub/gnu/"
+ DIE=1
+}
+
+if test "$DIE" -eq 1; then
+ exit 1
+fi
+
+if test -z "$*"; then
+ echo "**Warning**: I am going to run configure with no arguments."
+ echo "If you wish to pass any to it, please specify them on the"
+ echo $0 " command line."
+ echo
+fi
+
+case $CC in
+xlc )
+ am_opt=--include-deps;;
+esac
+
+aclocalinclude="$ACLOCAL_FLAGS"
+
+echo "Running libtoolize..."
+libtoolize --force --copy
+echo "Running aclocal $aclocalinclude ..."
+aclocal $aclocalinclude
+echo "Running gtkdocize..."
+gtkdocize
+echo "Running autoheader..."
+autoheader
+echo "Running automake --foreign -Wno-portability $am_opt ..."
+automake --add-missing --foreign -Wno-portability $am_opt
+echo "Running autoconf ..."
+autoconf
+
+conf_flags="--enable-maintainer-mode --enable-gtk-doc"
+
+if test x$NOCONFIGURE = x; then
+ echo "Running $srcdir/configure $conf_flags $@ ..."
+ $srcdir/configure $conf_flags "$@" \
+ && echo "Now type make to compile." || exit 1
+else
+ echo "Skipping configure process."
+fi
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..c2d263e
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,124 @@
+
+AC_INIT([Storage Configuration Library],[0.1],[mailto:zeuthen@gmail.com],[stc])
+AM_INIT_AUTOMAKE([1.9 foreign dist-bzip2 no-dist-gzip])
+AC_CONFIG_HEADERS([config.h])
+AM_MAINTAINER_MODE
+
+AC_PROG_CC
+AC_ISC_POSIX
+AC_HEADER_STDC
+AM_PROG_LIBTOOL
+
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
+
+#### gcc warning flags
+
+if test "x$GCC" = "xyes"; then
+ changequote(,)dnl
+ case " $CFLAGS " in
+ *[\ \ ]-Wall[\ \ ]*) ;;
+ *) CFLAGS="$CFLAGS -Wall" ;;
+ esac
+
+ case " $CFLAGS " in
+ *[\ \ ]-Wchar-subscripts[\ \ ]*) ;;
+ *) CFLAGS="$CFLAGS -Wchar-subscripts" ;;
+ esac
+
+ case " $CFLAGS " in
+ *[\ \ ]-Wmissing-declarations[\ \ ]*) ;;
+ *) CFLAGS="$CFLAGS -Wmissing-declarations" ;;
+ esac
+
+ case " $CFLAGS " in
+ *[\ \ ]-Wnested-externs[\ \ ]*) ;;
+ *) CFLAGS="$CFLAGS -Wnested-externs" ;;
+ esac
+
+ case " $CFLAGS " in
+ *[\ \ ]-Wpointer-arith[\ \ ]*) ;;
+ *) CFLAGS="$CFLAGS -Wpointer-arith" ;;
+ esac
+
+ case " $CFLAGS " in
+ *[\ \ ]-Wcast-align[\ \ ]*) ;;
+ *) CFLAGS="$CFLAGS -Wcast-align" ;;
+ esac
+
+ case " $CFLAGS " in
+ *[\ \ ]-Wsign-compare[\ \ ]*) ;;
+ *) CFLAGS="$CFLAGS -Wsign-compare" ;;
+ esac
+
+ case " $CFLAGS " in
+ *[\ \ ]-Wformat[\ \ ]*) ;;
+ *) CFLAGS="$CFLAGS -Wformat" ;;
+ esac
+
+ case " $CFLAGS " in
+ *[\ \ ]-Wformat-security[\ \ ]*) ;;
+ *) CFLAGS="$CFLAGS -Wformat-security" ;;
+ esac
+
+ if test "x$enable_ansi" = "xyes"; then
+ case " $CFLAGS " in
+ *[\ \ ]-ansi[\ \ ]*) ;;
+ *) CFLAGS="$CFLAGS -ansi" ;;
+ esac
+
+ case " $CFLAGS " in
+ *[\ \ ]-D_POSIX_C_SOURCE*) ;;
+ *) CFLAGS="$CFLAGS -D_POSIX_C_SOURCE=199309L" ;;
+ esac
+
+ case " $CFLAGS " in
+ *[\ \ ]-D_BSD_SOURCE[\ \ ]*) ;;
+ *) CFLAGS="$CFLAGS -D_BSD_SOURCE" ;;
+ esac
+
+ case " $CFLAGS " in
+ *[\ \ ]-pedantic[\ \ ]*) ;;
+ *) CFLAGS="$CFLAGS -pedantic" ;;
+ esac
+ fi
+ changequote([,])dnl
+fi
+
+GTK_DOC_CHECK([1.11])
+
+PKG_CHECK_MODULES(GLIB, gio-2.0 >= 2.25.9)
+AC_SUBST(GLIB_CFLAGS)
+AC_SUBST(GLIB_LIBS)
+
+PKG_CHECK_MODULES(GUDEV, gudev-1.0)
+AC_SUBST(GUDEV_CFLAGS)
+AC_SUBST(GUDEV_LIBS)
+
+AC_OUTPUT([
+Makefile
+stc/Makefile
+stc/stc-1.pc
+doc/Makefile
+])
+
+echo "
+ stc $VERSION
+ =========================
+
+ prefix: ${prefix}
+ libdir: ${libdir}
+ libexecdir: ${libexecdir}
+ bindir: ${bindir}
+ sbindir: ${sbindir}
+ datadir: ${datadir}
+ sysconfdir: ${sysconfdir}
+ localstatedir: ${localstatedir}
+ docdir: ${docdir}
+
+ compiler: ${CC}
+ cflags: ${CFLAGS}
+ cppflags: ${CPPFLAGS}
+
+ Maintainer mode: ${USE_MAINTAINER_MODE}
+ Building api docs: ${enable_gtk_doc}
+"
diff --git a/doc/Makefile.am b/doc/Makefile.am
new file mode 100644
index 0000000..8ebf073
--- /dev/null
+++ b/doc/Makefile.am
@@ -0,0 +1,86 @@
+NULL =
+
+# The name of the module.
+DOC_MODULE=stc
+
+# The top-level SGML file.
+DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.xml
+
+# Extra options to supply to gtkdoc-scan
+SCAN_OPTIONS=
+
+# The directory containing the source code. Relative to $(srcdir)
+DOC_SOURCE_DIR=$(top_srcdir)/stc
+
+HFILE_GLOB=$(top_srcdir)/stc/*.h
+CFILE_GLOB=$(top_srcdir)/stc/*.c
+
+# Headers to ignore
+IGNORE_HFILES= \
+ $(NULL)
+
+# CFLAGS and LDFLAGS for compiling scan program. Only needed
+# if $(DOC_MODULE).types is non-empty.
+INCLUDES = \
+ -I$(srcdir) \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/stc \
+ -I$(top_builddir) \
+ -I$(top_builddir)/stc \
+ $(GLIB_CFLAGS) \
+ $(NULL)
+
+GTKDOC_LIBS = \
+ $(GLIB_LIBS) \
+ $(top_builddir)/stc/libstc-1.la \
+ $(NULL)
+
+# Extra options to supply to gtkdoc-mkdb
+MKDB_OPTIONS = --output-format=xml --sgml-mode --name-space=stc
+
+# Images to copy into HTML directory
+HTML_IMAGES = \
+ $(NULL)
+
+content_files = \
+ $(NULL)
+
+expand_content_files = \
+ $(NULL)
+
+extra_files = \
+ $(NULL)
+
+include $(top_srcdir)/gtk-doc.make
+
+EXTRA_DIST += \
+ version.xml.in
+
+man_MANS = \
+ stc.1 \
+ $(NULL)
+
+.xml.1:
+ xsltproc -nonet http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $<
+
+MAINTAINERCLEANFILES = $(man_MANS) $(BUILT_SOURCES)
+
+EXTRA_DIST += $(man_MANS)
+
+CLEANFILES += \
+ $(DOC_MODULE)-decl-list.txt \
+ $(DOC_MODULE)-decl.txt \
+ $(DOC_MODULE)-overrides.txt \
+ $(DOC_MODULE)-undeclared.txt \
+ $(DOC_MODULE)-undocumented.txt \
+ $(DOC_MODULE)-unused.txt \
+ $(DOC_MODULE).args \
+ $(DOC_MODULE).hierarchy \
+ $(DOC_MODULE).interfaces \
+ $(DOC_MODULE).prerequisites \
+ $(DOC_MODULE).signals \
+ *.stamp \
+ -rf xml html tmpl \
+ stc.1 \
+ $(NULL)
+
diff --git a/doc/stc-docs.xml b/doc/stc-docs.xml
new file mode 100644
index 0000000..3c26e36
--- /dev/null
+++ b/doc/stc-docs.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
+<!ENTITY % local.common.attrib "xmlns:xi CDATA #FIXED 'http://www.w3.org/2003/XInclude'">
+<!ENTITY version SYSTEM "version.xml">
+]>
+<book lang="en" id="gio" xmlns:xi="http://www.w3.org/2003/XInclude">
+<title>stc Reference Manual</title>
+ <bookinfo>
+ <title>stc Reference Manual</title>
+ </bookinfo>
+
+ <part>
+ <title>Introduction</title>
+ </part>
+
+ <part>
+ <title>Library Reference</title>
+ <xi:include href="xml/stcerror.xml"/>
+ <xi:include href="xml/stcitem.xml"/>
+ <xi:include href="xml/stcmonitor.xml"/>
+ </part>
+
+ <part>
+ <title>Tools Reference</title>
+ <xi:include href="stc.xml"/>
+ </part>
+
+ <index>
+ <title>Index</title>
+ </index>
+
+ <chapter id="object-hierarchy">
+ <title>Object Hierarchy</title>
+ <xi:include href="xml/tree_index.sgml"/>
+ </chapter>
+
+</book>
diff --git a/doc/stc-sections.txt b/doc/stc-sections.txt
new file mode 100644
index 0000000..dd9dc48
--- /dev/null
+++ b/doc/stc-sections.txt
@@ -0,0 +1,48 @@
+<SECTION>
+<FILE>stcmonitor</FILE>
+<TITLE>StcMonitor</TITLE>
+StcMonitor
+stc_monitor_new
+stc_monitor_new_for_config_dir
+stc_monitor_get_config_dir
+stc_monitor_get_items
+<SUBSECTION Standard>
+STC_TYPE_MONITOR
+STC_MONITOR
+STC_IS_MONITOR
+<SUBSECTION Private>
+stc_monitor_get_type
+</SECTION>
+
+<SECTION>
+<FILE>stcitem</FILE>
+<TITLE>StcItem</TITLE>
+StcItem
+StcItemType
+stc_item_get_applied
+stc_item_get_can_apply
+stc_item_get_dependencies
+stc_item_get_id
+stc_item_get_item_type
+stc_item_get_nick_name
+stc_item_get_target
+stc_item_type_get_type
+<SUBSECTION Standard>
+STC_TYPE_ITEM
+STC_ITEM
+STC_IS_ITEM
+<SUBSECTION Private>
+stc_item_get_type
+STC_TYPE_ITEM_TYPE
+</SECTION>
+
+<SECTION>
+<FILE>stcerror</FILE>
+<TITLE>StcError</TITLE>
+STC_ERROR
+StcError
+<SUBSECTION Private>
+stc_error_quark
+stc_error_get_type
+STC_TYPE_ERROR
+</SECTION>
diff --git a/doc/stc.types b/doc/stc.types
new file mode 100644
index 0000000..c8825e2
--- /dev/null
+++ b/doc/stc.types
@@ -0,0 +1,2 @@
+stc_item_get_type
+stc_monitor_get_type
diff --git a/doc/stc.xml b/doc/stc.xml
new file mode 100644
index 0000000..84ee572
--- /dev/null
+++ b/doc/stc.xml
@@ -0,0 +1,43 @@
+<refentry id="stc" lang="en">
+<refmeta>
+ <refentrytitle>stc</refentrytitle>
+ <manvolnum>1</manvolnum>
+ <refmiscinfo class="manual">User Commands</refmiscinfo>
+</refmeta>
+
+<refnamediv>
+ <refname>stc</refname>
+ <refpurpose>Storage Configuration Tool</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+ <cmdsynopsis>
+ <command>stc</command>
+ </cmdsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+ <title>Description</title>
+ <para>
+ <command>stc</command> is TODO.
+ </para>
+</refsect1>
+
+<refsect1>
+ <title>Author</title>
+ <para>
+ Written by David Zeuthen <email>zeuthen@gmail.com</email> with
+ a lot of help from many others.
+ </para>
+</refsect1>
+
+<refsect1>
+ <title>See also</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>udisks</refentrytitle><manvolnum>1</manvolnum>
+ </citerefentry>
+ </para>
+</refsect1>
+
+</refentry>
diff --git a/stc/Makefile.am b/stc/Makefile.am
new file mode 100644
index 0000000..3ed139a
--- /dev/null
+++ b/stc/Makefile.am
@@ -0,0 +1,129 @@
+## Process this file with automake to produce Makefile.in
+
+SUBDIRS =
+
+NULL =
+
+INCLUDES = \
+ -I$(top_builddir)/src -I$(top_srcdir)/src \
+ -DPACKAGE_LIBEXEC_DIR=\""$(libexecdir)"\" \
+ -DPACKAGE_SYSCONF_DIR=\""$(sysconfdir)"\" \
+ -DPACKAGE_DATA_DIR=\""$(datadir)"\" \
+ -DPACKAGE_BIN_DIR=\""$(bindir)"\" \
+ -DPACKAGE_LOCALSTATE_DIR=\""$(localstatedir)"\" \
+ -DPACKAGE_LOCALE_DIR=\""$(localedir)"\" \
+ -DPACKAGE_LIB_DIR=\""$(libdir)"\" \
+ -DSRCDIR=\""$(srcdir)"\" \
+ -D_POSIX_PTHREAD_SEMANTICS -D_REENTRANT \
+ -DSTC_COMPILATION \
+ $(GLIB_CFLAGS) \
+ $(NULL)
+
+stcenumtypes.h: stcenums.h stcenumtypes.h.template
+ ( top_builddir=`cd $(top_builddir) && pwd`; \
+ cd $(srcdir) && glib-mkenums --template stcenumtypes.h.template stcenums.h ) > \
+ stcenumtypes.h.tmp && mv stcenumtypes.h.tmp stcenumtypes.h
+
+stcenumtypes.c: stcenums.h stcenumtypes.c.template
+ ( top_builddir=`cd $(top_builddir) && pwd`; \
+ cd $(srcdir) && glib-mkenums --template stcenumtypes.c.template stcenums.h ) > \
+ stcenumtypes.c.tmp && mv stcenumtypes.c.tmp stcenumtypes.c
+
+BUILT_SOURCES = \
+ stcenumtypes.h stcenumtypes.c \
+ $(NULL)
+
+lib_LTLIBRARIES=libstc-1.la
+
+libstc_1includedir=$(includedir)/stc-1/stc
+
+libstc_1include_HEADERS= \
+ stc.h \
+ stcenums.h \
+ stcenumtypes.h \
+ stcerror.h \
+ stcitem.h \
+ stcmonitor.h \
+ $(NULL)
+
+libstc_1_la_SOURCES = \
+ $(BUILT_SOURCES) \
+ stcenums.h \
+ stcerror.h stcerror.c \
+ stcitem.h stcitem.c \
+ stcmonitor.h stcmonitor.c \
+ $(NULL)
+
+libstc_1_la_CPPFLAGS = \
+ -DG_LOG_DOMAIN=\"libstc-1\" \
+ $(NULL)
+
+libstc_1_la_CFLAGS = \
+ $(GLIB_CFLAGS) \
+ $(NULL)
+
+libstc_1_la_LIBADD = \
+ $(GLIB_LIBS) \
+ $(NULL)
+
+# ----------------------------------------------------------------------------------------------------
+
+sbin_PROGRAMS = stc
+
+stc_SOURCES = \
+ stc.c \
+ $(NULL)
+
+stc_CPPFLAGS = \
+ -DG_LOG_DOMAIN=\"stc\" \
+ $(NULL)
+
+stc_CFLAGS = \
+ $(GLIB_CFLAGS) \
+ $(NULL)
+
+stc_LDFLAGS = \
+ $(GLIB_LIBS) \
+ libstc-1.la \
+ $(NULL)
+
+# ----------------------------------------------------------------------------------------------------
+
+TESTS = stc-test
+
+noinst_PROGRAMS = stc-test
+
+stc_test_SOURCES = \
+ test.c \
+ $(NULL)
+
+stc_test_CFLAGS = \
+ -DG_LOG_DOMAIN=\"stc-test\" \
+ $(NULL)
+
+stc_test_LDADD = \
+ $(GLIB_LIBS) \
+ libstc-1.la \
+ $(NULL)
+
+# ----------------------------------------------------------------------------------------------------
+
+profiledir = $(sysconfdir)/profile.d
+profile_SCRIPTS = stc-bash-completion.sh
+
+# ----------------------------------------------------------------------------------------------------
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = stc-1.pc
+
+# ----------------------------------------------------------------------------------------------------
+
+CLEANFILES =
+
+EXTRA_DIST = \
+ $(profile_SCRIPTS) \
+ stc-1.pc.in \
+ $(NULL)
+
+clean-local :
+ rm -f *~ $(BUILT_SOURCES)
diff --git a/stc/stc-1.pc.in b/stc/stc-1.pc.in
new file mode 100644
index 0000000..fcd6516
--- /dev/null
+++ b/stc/stc-1.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: stc-1
+Description: Storage Configuration Library
+Version: @VERSION@
+Requires: gobject-2.0 gio-2.0
+Libs: -L${libdir} -lstc-1
+Cflags: -I${includedir}/stc-1
diff --git a/stc/stc-bash-completion.sh b/stc/stc-bash-completion.sh
new file mode 100644
index 0000000..d014ae7
--- /dev/null
+++ b/stc/stc-bash-completion.sh
@@ -0,0 +1,33 @@
+
+# Check for bash
+[ -z "$BASH_VERSION" ] && return
+
+####################################################################################################
+
+
+__stc() {
+ local IFS=$'\n'
+ local cur=`_get_cword :`
+
+ local suggestions=$(stc complete "${COMP_LINE}" ${COMP_POINT})
+ COMPREPLY=($(compgen -W "$suggestions" -- "$cur"))
+
+ # Remove colon-word prefix from COMPREPLY items
+ case "$cur" in
+ *:*)
+ case "$COMP_WORDBREAKS" in
+ *:*)
+ local colon_word=${cur%${cur##*:}}
+ local i=${#COMPREPLY[*]}
+ while [ $((--i)) -ge 0 ]; do
+ COMPREPLY[$i]=${COMPREPLY[$i]#"$colon_word"}
+ done
+ ;;
+ esac
+ ;;
+ esac
+}
+
+####################################################################################################
+
+complete -o nospace -F __stc stc
diff --git a/stc/stc.c b/stc/stc.c
new file mode 100644
index 0000000..bac1f5b
--- /dev/null
+++ b/stc/stc.c
@@ -0,0 +1,516 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2007-2010 David Zeuthen <zeuthen@gmail.com>
+ *
+ * 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 of the licence, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: David Zeuthen <zeuthen@gmail.com>
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "stc.h"
+
+static GMainLoop *loop = NULL;
+
+/* Uncomment to get debug traces in /tmp/stc-completion-debug.txt - use tail(1) to
+ * inspect this file
+ */
+/* #define COMPLETION_DEBUG */
+//#define COMPLETION_DEBUG
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+G_GNUC_UNUSED static void completion_debug (const gchar *format, ...);
+
+static void remove_arg (gint num, gint *argc, gchar **argv[]);
+static void modify_argv0_for_command (gint *argc, gchar **argv[], const gchar *command);
+
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+typedef enum
+{
+ _COLOR_RESET,
+ _COLOR_BOLD_ON,
+ _COLOR_INVERSE_ON,
+ _COLOR_BOLD_OFF,
+ _COLOR_FG_BLACK,
+ _COLOR_FG_RED,
+ _COLOR_FG_GREEN,
+ _COLOR_FG_YELLOW,
+ _COLOR_FG_BLUE,
+ _COLOR_FG_MAGENTA,
+ _COLOR_FG_CYAN,
+ _COLOR_FG_WHITE,
+ _COLOR_BG_RED,
+ _COLOR_BG_GREEN,
+ _COLOR_BG_YELLOW,
+ _COLOR_BG_BLUE,
+ _COLOR_BG_MAGENTA,
+ _COLOR_BG_CYAN,
+ _COLOR_BG_WHITE
+} _Color;
+
+static gboolean _color_stdin_is_tty = FALSE;
+static gboolean _color_initialized = FALSE;
+static FILE *_color_pager_out = NULL;
+
+static void
+_color_init (void)
+{
+ if (_color_initialized)
+ return;
+ _color_initialized = TRUE;
+ _color_stdin_is_tty = (isatty (STDIN_FILENO) != 0 && isatty (STDOUT_FILENO) != 0);
+}
+
+static void
+_color_shutdown (void)
+{
+ if (!_color_initialized)
+ return;
+ _color_initialized = FALSE;
+ if (_color_pager_out != NULL)
+ pclose (_color_pager_out);
+}
+
+static const gchar *
+_color_get (_Color color)
+{
+ const gchar *str;
+
+ _color_init ();
+
+ if (!_color_stdin_is_tty)
+ return "";
+
+ str = NULL;
+ switch (color)
+ {
+ case _COLOR_RESET: str="\x1b[0m"; break;
+ case _COLOR_BOLD_ON: str="\x1b[1m"; break;
+ case _COLOR_INVERSE_ON: str="\x1b[7m"; break;
+ case _COLOR_BOLD_OFF: str="\x1b[22m"; break;
+ case _COLOR_FG_BLACK: str="\x1b[30m"; break;
+ case _COLOR_FG_RED: str="\x1b[31m"; break;
+ case _COLOR_FG_GREEN: str="\x1b[32m"; break;
+ case _COLOR_FG_YELLOW: str="\x1b[33m"; break;
+ case _COLOR_FG_BLUE: str="\x1b[34m"; break;
+ case _COLOR_FG_MAGENTA: str="\x1b[35m"; break;
+ case _COLOR_FG_CYAN: str="\x1b[36m"; break;
+ case _COLOR_FG_WHITE: str="\x1b[37m"; break;
+ case _COLOR_BG_RED: str="\x1b[41m"; break;
+ case _COLOR_BG_GREEN: str="\x1b[42m"; break;
+ case _COLOR_BG_YELLOW: str="\x1b[43m"; break;
+ case _COLOR_BG_BLUE: str="\x1b[44m"; break;
+ case _COLOR_BG_MAGENTA: str="\x1b[45m"; break;
+ case _COLOR_BG_CYAN: str="\x1b[46m"; break;
+ case _COLOR_BG_WHITE: str="\x1b[47m"; break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+ return str;
+}
+
+static void
+_color_run_pager (void)
+{
+ const gchar *pager_program;
+
+ _color_init ();
+ if (!_color_stdin_is_tty)
+ goto out;
+
+ pager_program = g_getenv ("PAGER");
+ if (pager_program == NULL)
+ pager_program = "less -R";
+
+ _color_pager_out = popen (pager_program, "w");
+ if (_color_pager_out == NULL)
+ {
+ g_printerr ("Error spawning pager `%s': %m\n", pager_program);
+ }
+ else
+ {
+ fclose (stdout);
+ stdout = _color_pager_out;
+ }
+
+ out:
+ ;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static const GOptionEntry command_list_entries[] =
+{
+ { NULL }
+};
+
+static gint
+handle_command_list (gint *argc,
+ gchar **argv[],
+ gboolean request_completion,
+ const gchar *completion_cur,
+ const gchar *completion_prev)
+{
+ gint ret;
+ GOptionContext *o;
+ gchar *s;
+
+ ret = 1;
+
+ modify_argv0_for_command (argc, argv, "list");
+
+ o = g_option_context_new (NULL);
+ if (request_completion)
+ g_option_context_set_ignore_unknown_options (o, TRUE);
+ g_option_context_set_help_enabled (o, FALSE);
+ g_option_context_set_summary (o, "List configuration entries.");
+ g_option_context_add_main_entries (o, command_list_entries, NULL /* GETTEXT_PACKAGE*/);
+
+ if (!g_option_context_parse (o, argc, argv, NULL))
+ {
+ if (!request_completion)
+ {
+ s = g_option_context_get_help (o, FALSE, NULL);
+ g_printerr ("%s", s);
+ g_free (s);
+ goto out;
+ }
+ }
+
+ /* done with completion */
+ if (request_completion)
+ goto out;
+
+ _color_run_pager ();
+
+ g_print ("%sfoo%s\n",
+ _color_get (_COLOR_FG_RED),
+ _color_get (_COLOR_RESET));
+
+ ret = 0;
+
+ out:
+ g_option_context_free (o);
+ return ret;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+usage (gint *argc, gchar **argv[], gboolean use_stdout)
+{
+ GOptionContext *o;
+ gchar *s;
+ gchar *program_name;
+
+ o = g_option_context_new ("COMMAND");
+ g_option_context_set_help_enabled (o, FALSE);
+ /* Ignore parsing result */
+ g_option_context_parse (o, argc, argv, NULL);
+ program_name = g_path_get_basename ((*argv)[0]);
+ s = g_strdup_printf ("Commands:\n"
+ " help Shows this information\n"
+ //" info Shows information about an object\n"
+ " list Lists all configuration entries\n"
+ //" apply Mount a device\n"
+ //" unapply Unmount a device\n"
+ "\n"
+ "Use \"%s COMMAND --help\" to get help on each command.\n",
+ program_name);
+ g_free (program_name);
+ g_option_context_set_description (o, s);
+ g_free (s);
+ s = g_option_context_get_help (o, FALSE, NULL);
+ if (use_stdout)
+ g_print ("%s", s);
+ else
+ g_printerr ("%s", s);
+ g_free (s);
+ g_option_context_free (o);
+}
+
+static void
+remove_arg (gint num, gint *argc, gchar **argv[])
+{
+ gint n;
+
+ g_assert (num <= (*argc));
+
+ for (n = num; (*argv)[n] != NULL; n++)
+ (*argv)[n] = (*argv)[n+1];
+ (*argv)[n] = NULL;
+ (*argc) = (*argc) - 1;
+}
+
+static void
+modify_argv0_for_command (gint *argc, gchar **argv[], const gchar *command)
+{
+ gchar *s;
+ gchar *program_name;
+
+ /* TODO:
+ * 1. get a g_set_prgname() ?; or
+ * 2. save old argv[0] and restore later
+ */
+
+ g_assert (g_strcmp0 ((*argv)[1], command) == 0);
+ remove_arg (1, argc, argv);
+
+ program_name = g_path_get_basename ((*argv)[0]);
+ s = g_strdup_printf ("%s %s", (*argv)[0], command);
+ (*argv)[0] = s;
+ g_free (program_name);
+}
+
+static gchar *
+pick_word_at (const gchar *s,
+ gint cursor,
+ gint *out_word_begins_at)
+{
+ gint begin;
+ gint end;
+
+ if (s[0] == '\0')
+ {
+ if (out_word_begins_at != NULL)
+ *out_word_begins_at = -1;
+ return NULL;
+ }
+
+ if (g_ascii_isspace (s[cursor]) && ((cursor > 0 && g_ascii_isspace(s[cursor-1])) || cursor == 0))
+ {
+ if (out_word_begins_at != NULL)
+ *out_word_begins_at = cursor;
+ return g_strdup ("");
+ }
+
+ while (!g_ascii_isspace (s[cursor - 1]) && cursor > 0)
+ cursor--;
+ begin = cursor;
+
+ end = begin;
+ while (!g_ascii_isspace (s[end]) && s[end] != '\0')
+ end++;
+
+ if (out_word_begins_at != NULL)
+ *out_word_begins_at = begin;
+
+ return g_strndup (s + begin, end - begin);
+}
+
+/* TODO: would be nice with generic options that can be used before any verb such as
+ *
+ * -n, --no-color Turn colorization off always.
+ * -C, --color Turn colorization on always.
+ */
+
+int
+main (int argc, char *argv[])
+{
+ gint ret;
+ const gchar *command;
+ gboolean request_completion;
+ gchar *completion_cur;
+ gchar *completion_prev;
+
+ ret = 1;
+ completion_cur = NULL;
+ completion_prev = NULL;
+ loop = NULL;
+
+ g_type_init ();
+ _color_init ();
+
+ if (argc < 2)
+ {
+ usage (&argc, &argv, FALSE);
+ goto out;
+ }
+
+ loop = g_main_loop_new (NULL, FALSE);
+
+ request_completion = FALSE;
+
+ completion_debug ("========================================================================");
+ completion_debug ("---- argc=%d --------------------------------------------------------", argc);
+
+ again:
+ command = argv[1];
+ if (g_strcmp0 (command, "help") == 0)
+ {
+ if (request_completion)
+ {
+ /* do nothing */
+ }
+ else
+ {
+ usage (&argc, &argv, TRUE);
+ ret = 0;
+ }
+ goto out;
+ }
+#if 0
+ else if (g_strcmp0 (command, "info") == 0)
+ {
+ ret = handle_command_info (&argc,
+ &argv,
+ request_completion,
+ completion_cur,
+ completion_prev);
+ goto out;
+ }
+#endif
+ else if (g_strcmp0 (command, "list") == 0)
+ {
+ ret = handle_command_list (&argc,
+ &argv,
+ request_completion,
+ completion_cur,
+ completion_prev);
+ goto out;
+ }
+#if 0
+ else if (g_strcmp0 (command, "apply") == 0 || g_strcmp0 (command, "unapply") == 0)
+ {
+ ret = handle_command_apply_unapply (&argc,
+ &argv,
+ request_completion,
+ completion_cur,
+ completion_prev,
+ g_strcmp0 (command, "apply") == 0);
+ goto out;
+ }
+#endif
+ else if (g_strcmp0 (command, "complete") == 0 && argc == 4 && !request_completion)
+ {
+ const gchar *completion_line;
+ gchar **completion_argv;
+ gint completion_argc;
+ gint completion_point;
+ gchar *endp;
+ gint cur_begin;
+
+ request_completion = TRUE;
+
+ completion_line = argv[2];
+ completion_point = strtol (argv[3], &endp, 10);
+ if (endp == argv[3] || *endp != '\0')
+ goto out;
+
+ completion_debug ("completion_point=%d", completion_point);
+ completion_debug ("----");
+ completion_debug (" 0123456789012345678901234567890123456789012345678901234567890123456789");
+ completion_debug ("`%s'", completion_line);
+ completion_debug (" %*s^",
+ completion_point, "");
+ completion_debug ("----");
+
+ if (!g_shell_parse_argv (completion_line,
+ &completion_argc,
+ &completion_argv,
+ NULL))
+ {
+ /* it's very possible the command line can't be parsed (for
+ * example, missing quotes etc) - in that case, we just
+ * don't autocomplete at all
+ */
+ goto out;
+ }
+
+ /* compute cur and prev */
+ completion_prev = NULL;
+ completion_cur = pick_word_at (completion_line, completion_point, &cur_begin);
+ if (cur_begin > 0)
+ {
+ gint prev_end;
+ for (prev_end = cur_begin - 1; prev_end >= 0; prev_end--)
+ {
+ if (!g_ascii_isspace (completion_line[prev_end]))
+ {
+ completion_prev = pick_word_at (completion_line, prev_end, NULL);
+ break;
+ }
+ }
+ }
+ completion_debug (" cur=`%s'", completion_cur);
+ completion_debug ("prev=`%s'", completion_prev);
+
+ argc = completion_argc;
+ argv = completion_argv;
+
+ ret = 0;
+
+ goto again;
+ }
+ else
+ {
+ if (request_completion)
+ {
+ g_print ("help \n"
+ //"info \n"
+ "list \n"
+ //"apply \n"
+ //"unapply \n"
+ );
+ ret = 0;
+ goto out;
+ }
+ else
+ {
+ g_printerr ("Unknown command `%s'\n", command);
+ usage (&argc, &argv, FALSE);
+ goto out;
+ }
+ }
+
+ out:
+ if (loop != NULL)
+ g_main_loop_unref (loop);
+ _color_shutdown ();
+ return ret;
+}
+
+#ifdef COMPLETION_DEBUG
+G_GNUC_UNUSED static void
+completion_debug (const gchar *format, ...)
+{
+ va_list var_args;
+ gchar *s;
+ static FILE *f = NULL;
+
+ va_start (var_args, format);
+ s = g_strdup_vprintf (format, var_args);
+ if (f == NULL)
+ {
+ f = fopen ("/tmp/stc-completion-debug.txt", "a+");
+ }
+ fprintf (f, "%s\n", s);
+ g_free (s);
+}
+#else
+static void
+completion_debug (const gchar *format, ...)
+{
+}
+#endif
diff --git a/stc/stc.conf b/stc/stc.conf
new file mode 100644
index 0000000..1ffec32
--- /dev/null
+++ b/stc/stc.conf
@@ -0,0 +1,20 @@
+[Filesystem BigStorage]
+NickName=BigStorage
+Device=/dev/disk/md-uuid-01234:56789
+Depends=BigStorage_mdraid
+Auto=yes
+
+[MDRaid BigStorage_mdraid]
+NickName=BigStorage RAID Array
+UUID=01234:56789
+
+[Filesystem SekritStuff]
+NickName=My Secret Stuff
+Device=/dev/disk/by-uuid/1234
+Options=Filesystem:options=noatime,dirsync
+Depends=SekritStuff_LUKS
+
+[LUKS SekritStuff_LUKS]
+NickName=My Secret Stuff (Encrypted)
+Device=/dev/disk/by-uuid/12345
+Options=LUKS:password=xyz123
diff --git a/stc/stc.h b/stc/stc.h
new file mode 100644
index 0000000..aba2fd1
--- /dev/null
+++ b/stc/stc.h
@@ -0,0 +1,39 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2007-2010 David Zeuthen <zeuthen@gmail.com>
+ *
+ * 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 of the licence, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: David Zeuthen <zeuthen@gmail.com>
+ */
+
+#ifndef __STC_H__
+#define __STC_H__
+
+#if !defined(STC_API_IS_SUBJECT_TO_CHANGE) && !defined(STC_COMPILATION)
+#error libstc is unstable API. You must define STC_API_IS_SUBJECT_TO_CHANGE before including stc/stc.h
+#endif
+
+#define __STC_INSIDE_STC_H__
+#include <stc/stctypes.h>
+#include <stc/stcenums.h>
+#include <stc/stcenumtypes.h>
+#include <stc/stcerror.h>
+#include <stc/stcitem.h>
+#include <stc/stcmonitor.h>
+#undef __STC_INSIDE_STC_H__
+
+#endif /* __STC_H__ */
diff --git a/stc/stcenums.h b/stc/stcenums.h
new file mode 100644
index 0000000..49065a2
--- /dev/null
+++ b/stc/stcenums.h
@@ -0,0 +1,61 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2007-2010 David Zeuthen <zeuthen@gmail.com>
+ *
+ * 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 of the licence, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: David Zeuthen <zeuthen@gmail.com>
+ */
+
+#if !defined (__STC_INSIDE_STC_H__) && !defined (STC_COMPILATION)
+#error "Only <stc/stc.h> can be included directly."
+#endif
+
+#ifndef __STC_ENUMS_H__
+#define __STC_ENUMS_H__
+
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+/**
+ * StcError:
+ * @STC_ERROR_FAILED: The operation failed.
+ *
+ * Error codes for the #STC_ERROR error domain and the
+ * corresponding D-Bus error names.
+ */
+typedef enum
+{
+ STC_ERROR_FAILED
+} StcError;
+
+/**
+ * StcItemType:
+ * @STC_ITEM_TYPE_INVALID: Unknown or invalid item type.
+ * @STC_ITEM_TYPE_FSMOUNT: Filesystem mount.
+ *
+ * Enumeration describing item types.
+ */
+typedef enum
+{
+ STC_ITEM_TYPE_INVALID,
+ STC_ITEM_TYPE_FSMOUNT
+} StcItemType;
+
+G_END_DECLS
+
+#endif /* __STC_ENUMS_H__ */
diff --git a/stc/stcenumtypes.c.template b/stc/stcenumtypes.c.template
new file mode 100644
index 0000000..a54b192
--- /dev/null
+++ b/stc/stcenumtypes.c.template
@@ -0,0 +1,40 @@
+/*** BEGIN file-header ***/
+#include "stcenums.h"
+#include "stcenumtypes.h"
+
+/*** END file-header ***/
+
+/*** BEGIN file-production ***/
+/* enumerations from "@filename@" */
+/*** END file-production ***/
+
+/*** BEGIN value-header ***/
+GType
+@enum_name@_get_type (void)
+{
+ static volatile gsize g_define_type_id__volatile = 0;
+
+ if (g_once_init_enter (&g_define_type_id__volatile))
+ {
+ static const G@Type@Value values[] = {
+/*** END value-header ***/
+
+/*** BEGIN value-production ***/
+ { @VALUENAME@, "@VALUENAME@", "@valuenick@" },
+/*** END value-production ***/
+
+/*** BEGIN value-tail ***/
+ { 0, NULL, NULL }
+ };
+ GType g_define_type_id =
+ g_@type@_register_static (g_intern_static_string ("@EnumName@"), values);
+ g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
+ }
+
+ return g_define_type_id__volatile;
+}
+
+/*** END value-tail ***/
+
+/*** BEGIN file-tail ***/
+/*** END file-tail ***/
diff --git a/stc/stcenumtypes.h.template b/stc/stcenumtypes.h.template
new file mode 100644
index 0000000..9b95ca4
--- /dev/null
+++ b/stc/stcenumtypes.h.template
@@ -0,0 +1,24 @@
+/*** BEGIN file-header ***/
+#ifndef __STC_ENUM_TYPES_H__
+#define __STC_ENUM_TYPES_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+/*** END file-header ***/
+
+/*** BEGIN file-production ***/
+
+/* enumerations from "@filename@" */
+/*** END file-production ***/
+
+/*** BEGIN value-header ***/
+GType @enum_name@_get_type (void) G_GNUC_CONST;
+#define @ENUMPREFIX@_TYPE_@ENUMSHORT@ (@enum_name@_get_type ())
+/*** END value-header ***/
+
+/*** BEGIN file-tail ***/
+G_END_DECLS
+
+#endif /* __STC_ENUM_TYPES_H__ */
+/*** END file-tail ***/
diff --git a/stc/stcerror.c b/stc/stcerror.c
new file mode 100644
index 0000000..1012d81
--- /dev/null
+++ b/stc/stcerror.c
@@ -0,0 +1,39 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2007-2010 David Zeuthen <zeuthen@gmail.com>
+ *
+ * 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 of the licence, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: David Zeuthen <zeuthen@gmail.com>
+ */
+
+#include "config.h"
+
+#include "stcerror.h"
+
+/**
+ * SECTION:stcerror
+ * @title: StcError
+ * @short_description: Error domain
+ *
+ * Error codes.
+ */
+
+GQuark
+stc_error_quark (void)
+{
+ return g_quark_from_static_string ("stc-error-quark");
+}
diff --git a/stc/stcerror.h b/stc/stcerror.h
new file mode 100644
index 0000000..89ef01a
--- /dev/null
+++ b/stc/stcerror.h
@@ -0,0 +1,47 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2007-2010 David Zeuthen <zeuthen@gmail.com>
+ *
+ * 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 of the licence, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: David Zeuthen <zeuthen@gmail.com>
+ */
+
+#if !defined (__STC_INSIDE_STC_H__) && !defined (STC_COMPILATION)
+#error "Only <stc/stc.h> can be included directly."
+#endif
+
+#ifndef __STC_ERROR_H__
+#define __STC_ERROR_H__
+
+#include <stc/stctypes.h>
+
+G_BEGIN_DECLS
+
+/**
+ * STC_ERROR:
+ *
+ * Error domain for Stc. Errors in this domain will be form the
+ * #StcError enumeration. See #GError for more information on error
+ * domains.
+ */
+#define STC_ERROR (stc_error_quark ())
+
+GQuark stc_error_quark (void);
+
+G_END_DECLS
+
+#endif /* __STC_ERROR_H__ */
diff --git a/stc/stcitem.c b/stc/stcitem.c
new file mode 100644
index 0000000..fda895b
--- /dev/null
+++ b/stc/stcitem.c
@@ -0,0 +1,162 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2007-2010 David Zeuthen <zeuthen@gmail.com>
+ *
+ * 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 of the licence, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: David Zeuthen <zeuthen@gmail.com>
+ */
+
+#include "config.h"
+
+#include "stcitem.h"
+
+/**
+ * SECTION:stcitem
+ * @title: StcItem
+ * @short_description: Configuration Item
+ *
+ * Object corresponding to item. You cannot instantiate this type
+ * yourself – you must use #StcMonitor.
+ */
+
+/**
+ * StcItem:
+ *
+ * The #StcItem structure contains only private data and should
+ * only be accessed using the provided API.
+ */
+struct _StcItem
+{
+ GObject parent_instance;
+
+ StcItemType type;
+ gchar *id;
+ gchar *nick_name;
+ gchar *target;
+ gboolean can_apply;
+ gboolean applied;
+};
+
+typedef struct _StcItemClass StcItemClass;
+
+struct _StcItemClass
+{
+ GObjectClass parent_class;
+};
+
+G_DEFINE_TYPE (StcItem, stc_item, G_TYPE_OBJECT);
+
+static void
+stc_item_finalize (GObject *object)
+{
+ StcItem *item = STC_ITEM (object);
+
+ g_free (item->id);
+ g_free (item->nick_name);
+ g_free (item->target);
+
+ if (G_OBJECT_CLASS (stc_item_parent_class)->finalize)
+ G_OBJECT_CLASS (stc_item_parent_class)->finalize (object);
+}
+
+static void
+stc_item_init (StcItem *item)
+{
+}
+
+static void
+stc_item_class_init (StcItemClass *klass)
+{
+ GObjectClass *gobject_class;
+
+ gobject_class = G_OBJECT_CLASS (klass);
+ gobject_class->finalize = stc_item_finalize;
+}
+
+/**
+ * stc_item_get_item_type:
+ * @item: A #StcItem.
+ *
+ * Gets the #StcItemType for @item.
+ *
+ * Returns: A value from the #StcItemType enumeration.
+ */
+StcItemType
+stc_item_get_item_type (StcItem *item)
+{
+ g_return_val_if_fail (STC_IS_ITEM (item), STC_ITEM_TYPE_INVALID);
+ return item->type;
+}
+
+const gchar *
+stc_item_get_id (StcItem *item)
+{
+ g_return_val_if_fail (STC_IS_ITEM (item), STC_ITEM_TYPE_INVALID);
+ return item->id;
+}
+
+const gchar *
+stc_item_get_nick_name (StcItem *item)
+{
+ g_return_val_if_fail (STC_IS_ITEM (item), NULL);
+ return item->nick_name;
+}
+
+const gchar *
+stc_item_get_target (StcItem *item)
+{
+ g_return_val_if_fail (STC_IS_ITEM (item), NULL);
+ return item->target;
+}
+
+GList *
+stc_item_get_dependencies (StcItem *item)
+{
+ g_return_val_if_fail (STC_IS_ITEM (item), FALSE);
+ /* TODO */
+ return NULL;
+}
+
+gboolean
+stc_item_get_can_apply (StcItem *item)
+{
+ g_return_val_if_fail (STC_IS_ITEM (item), FALSE);
+ return item->can_apply;
+}
+
+gboolean
+stc_item_get_applied (StcItem *item)
+{
+ g_return_val_if_fail (STC_IS_ITEM (item), FALSE);
+ return item->applied;
+}
+
+
+#if 0
+StcItem *
+_stc_item_new (dev_t dev,
+ const gchar *item_path)
+{
+ StcItem *item;
+
+ item = STC_ITEM (g_object_new (STC_TYPE_ITEM, NULL));
+ item->dev = dev;
+ item->item_path = g_strdup (item_path);
+
+ return item;
+}
+#endif
diff --git a/stc/stcitem.h b/stc/stcitem.h
new file mode 100644
index 0000000..a666549
--- /dev/null
+++ b/stc/stcitem.h
@@ -0,0 +1,50 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2007-2010 David Zeuthen <zeuthen@gmail.com>
+ *
+ * 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 of the licence, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: David Zeuthen <zeuthen@gmail.com>
+ */
+
+
+#if !defined (__STC_INSIDE_STC_H__) && !defined (STC_COMPILATION)
+#error "Only <stc/stc.h> can be included directly."
+#endif
+
+#ifndef __STC_ITEM_H__
+#define __STC_ITEM_H__
+
+#include <stc/stctypes.h>
+
+G_BEGIN_DECLS
+
+#define STC_TYPE_ITEM (stc_item_get_type ())
+#define STC_ITEM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), STC_TYPE_ITEM, StcItem))
+#define STC_IS_ITEM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), STC_TYPE_ITEM))
+
+GType stc_item_get_type (void) G_GNUC_CONST;
+StcItemType stc_item_get_item_type (StcItem *item);
+const gchar *stc_item_get_id (StcItem *item);
+const gchar *stc_item_get_nick_name (StcItem *item);
+const gchar *stc_item_get_target (StcItem *item);
+GList *stc_item_get_dependencies (StcItem *item);
+gboolean stc_item_get_can_apply (StcItem *item);
+gboolean stc_item_get_applied (StcItem *item);
+
+G_END_DECLS
+
+#endif /* __STC_ITEM_H__ */
diff --git a/stc/stcmonitor.c b/stc/stcmonitor.c
new file mode 100644
index 0000000..dc1bc0f
--- /dev/null
+++ b/stc/stcmonitor.c
@@ -0,0 +1,198 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2007-2010 David Zeuthen <zeuthen@gmail.com>
+ *
+ * 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 of the licence, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: David Zeuthen <zeuthen@gmail.com>
+ */
+
+#include "config.h"
+
+#include "stcmonitor.h"
+
+/**
+ * SECTION:stcmonitor
+ * @title: StcMonitor
+ * @short_description: Retrieve, change, create and monitor items
+ *
+ * Object used to retrieve, change, create and monitor configuration
+ * items.
+ */
+
+/**
+ * StcMonitor:
+ *
+ * The #StcMonitor structure contains only private data and should
+ * only be accessed using the provided API.
+ */
+struct _StcMonitor
+{
+ GObject parent_instance;
+
+ gchar *config_dir;
+
+ GList *items;
+};
+
+typedef struct _StcMonitorClass StcMonitorClass;
+
+struct _StcMonitorClass
+{
+ GObjectClass parent_class;
+};
+
+enum
+{
+ PROP_0,
+ PROP_CONFIG_DIR
+};
+
+G_DEFINE_TYPE (StcMonitor, stc_monitor, G_TYPE_OBJECT);
+
+static void
+stc_monitor_finalize (GObject *object)
+{
+ StcMonitor *monitor = STC_MONITOR (object);
+
+ g_free (monitor->config_dir);
+ g_list_foreach (monitor->items, (GFunc) g_object_unref, NULL);
+ g_list_free (monitor->items);
+
+ if (G_OBJECT_CLASS (stc_monitor_parent_class)->finalize)
+ G_OBJECT_CLASS (stc_monitor_parent_class)->finalize (object);
+}
+
+static void
+stc_monitor_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ StcMonitor *monitor = STC_MONITOR (object);
+
+ switch (prop_id)
+ {
+ case PROP_CONFIG_DIR:
+ g_value_set_string (value, stc_monitor_get_config_dir (monitor));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+stc_monitor_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ StcMonitor *monitor = STC_MONITOR (object);
+
+ switch (prop_id)
+ {
+ case PROP_CONFIG_DIR:
+ g_assert (monitor->config_dir == NULL);
+ monitor->config_dir = g_value_dup_string (value);
+ g_assert (monitor->config_dir != NULL);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+stc_monitor_init (StcMonitor *monitor)
+{
+}
+
+
+static void
+stc_monitor_constructed (GObject *object)
+{
+ //StcMonitor *monitor = STC_MONITOR (object);
+
+ if (G_OBJECT_CLASS (stc_monitor_parent_class)->constructed)
+ G_OBJECT_CLASS (stc_monitor_parent_class)->constructed (object);
+}
+
+static void
+stc_monitor_class_init (StcMonitorClass *klass)
+{
+ GObjectClass *gobject_class;
+
+ gobject_class = G_OBJECT_CLASS (klass);
+ gobject_class->finalize = stc_monitor_finalize;
+ gobject_class->constructed = stc_monitor_constructed;
+ gobject_class->get_property = stc_monitor_get_property;
+ gobject_class->set_property = stc_monitor_set_property;
+
+ /**
+ * StcMonitor:config-dir:
+ *
+ * The path for the configuration directory. If set to %NULL at
+ * construction time, then the <filename>/etc</filename> directory is used.
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_CONFIG_DIR,
+ g_param_spec_string ("config-dir",
+ "Configuration Directory",
+ "The configuration directory",
+ PACKAGE_SYSCONF_DIR,
+ G_PARAM_READABLE |
+ G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+}
+
+StcMonitor *
+stc_monitor_new (void)
+{
+ StcMonitor *monitor;
+ monitor = STC_MONITOR (g_object_new (STC_TYPE_MONITOR, NULL));
+ return monitor;
+}
+
+StcMonitor *
+stc_monitor_new_for_config_dir (const gchar *config_dir)
+{
+ StcMonitor *monitor;
+
+ g_return_val_if_fail (config_dir != NULL, NULL);
+
+ monitor = STC_MONITOR (g_object_new (STC_TYPE_MONITOR,
+ "config-dir", config_dir,
+ NULL));
+ return monitor;
+}
+
+const gchar *
+stc_monitor_get_config_dir (StcMonitor *monitor)
+{
+ g_return_val_if_fail (STC_IS_MONITOR (monitor), NULL);
+ return monitor->config_dir;
+}
+
+GList *
+stc_monitor_get_items (StcMonitor *monitor)
+{
+ return NULL;
+}
+
diff --git a/stc/stcmonitor.h b/stc/stcmonitor.h
new file mode 100644
index 0000000..4cf2e3c
--- /dev/null
+++ b/stc/stcmonitor.h
@@ -0,0 +1,47 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2007-2010 David Zeuthen <zeuthen@gmail.com>
+ *
+ * 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 of the licence, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: David Zeuthen <zeuthen@gmail.com>
+ */
+
+
+#if !defined (__STC_INSIDE_STC_H__) && !defined (STC_COMPILATION)
+#error "Only <stc/stc.h> can be included directly."
+#endif
+
+#ifndef __STC_MONITOR_H__
+#define __STC_MONITOR_H__
+
+#include <stc/stctypes.h>
+
+G_BEGIN_DECLS
+
+#define STC_TYPE_MONITOR (stc_monitor_get_type ())
+#define STC_MONITOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), STC_TYPE_MONITOR, StcMonitor))
+#define STC_IS_MONITOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), STC_TYPE_MONITOR))
+
+GType stc_monitor_get_type (void) G_GNUC_CONST;
+StcMonitor *stc_monitor_new (void);
+StcMonitor *stc_monitor_new_for_config_dir (const gchar *config_dir);
+const gchar *stc_monitor_get_config_dir (StcMonitor *monitor);
+GList *stc_monitor_get_items (StcMonitor *monitor);
+
+G_END_DECLS
+
+#endif /* __STC_MONITOR_H__ */
diff --git a/stc/stctypes.h b/stc/stctypes.h
new file mode 100644
index 0000000..eaa560e
--- /dev/null
+++ b/stc/stctypes.h
@@ -0,0 +1,43 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2007-2010 David Zeuthen <zeuthen@gmail.com>
+ *
+ * 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 of the licence, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: David Zeuthen <zeuthen@gmail.com>
+ */
+
+#if !defined (__STC_INSIDE_STC_H__) && !defined (STC_COMPILATION)
+#error "Only <stc/stc.h> can be included directly."
+#endif
+
+#ifndef __STC_TYPES_H__
+#define __STC_TYPES_H__
+
+#include <gio/gio.h>
+#include <stc/stcenums.h>
+
+G_BEGIN_DECLS
+
+struct _StcItem;
+typedef struct _StcItem StcItem;
+
+struct _StcMonitor;
+typedef struct _StcMonitor StcMonitor;
+
+G_END_DECLS
+
+#endif /* __STC_TYPES_H__ */
diff --git a/stc/test.c b/stc/test.c
new file mode 100644
index 0000000..92bbfa7
--- /dev/null
+++ b/stc/test.c
@@ -0,0 +1,57 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2007-2010 David Zeuthen <david@fubar.dk>
+ *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include "config.h"
+
+#include "stc.h"
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+test_stc_basic (void)
+{
+ StcMonitor *monitor;
+
+ monitor = stc_monitor_new ();
+ g_assert_cmpstr (stc_monitor_get_config_dir (monitor), ==, PACKAGE_SYSCONF_DIR);
+ g_object_unref (monitor);
+
+ monitor = stc_monitor_new_for_config_dir (SRCDIR);
+ g_assert_cmpstr (stc_monitor_get_config_dir (monitor), ==, SRCDIR);
+ g_object_unref (monitor);
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+int
+main (int argc,
+ char **argv)
+{
+ gint ret;
+
+ g_type_init ();
+ g_test_init (&argc, &argv, NULL);
+
+ g_test_add_func ("/stc/basic", test_stc_basic);
+
+ ret = g_test_run();
+
+ return ret;
+}