Blame gio/gresource-tool.c

Packit ae235b
/*
Packit ae235b
 * Copyright © 2012 Red Hat, Inc
Packit ae235b
 *
Packit ae235b
 * This library is free software; you can redistribute it and/or
Packit ae235b
 * modify it under the terms of the GNU Lesser General Public
Packit ae235b
 * License as published by the Free Software Foundation; either
Packit ae235b
 * version 2.1 of the License, or (at your option) any later version.
Packit ae235b
 *
Packit ae235b
 * This library is distributed in the hope that it will be useful,
Packit ae235b
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit ae235b
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit ae235b
 * Lesser General Public License for more details.
Packit ae235b
 *
Packit ae235b
 * You should have received a copy of the GNU Lesser General Public
Packit ae235b
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
Packit ae235b
 *
Packit ae235b
 * Author: Matthias Clasen
Packit ae235b
 */
Packit ae235b
Packit ae235b
#include "config.h"
Packit ae235b
Packit ae235b
#include <stdlib.h>
Packit ae235b
#include <stdio.h>
Packit ae235b
Packit ae235b
#include <sys/types.h>
Packit ae235b
#include <sys/stat.h>
Packit ae235b
#include <fcntl.h>
Packit ae235b
#include <string.h>
Packit ae235b
#include <locale.h>
Packit ae235b
Packit ae235b
#ifdef HAVE_LIBELF
Packit ae235b
#include <libelf.h>
Packit ae235b
#include <gelf.h>
Packit ae235b
#include <sys/mman.h>
Packit ae235b
#endif
Packit ae235b
Packit ae235b
#include <gio/gio.h>
Packit ae235b
#include <glib/gstdio.h>
Packit ae235b
#include <gi18n.h>
Packit ae235b
Packit ae235b
#ifdef G_OS_WIN32
Packit ae235b
#include "glib/glib-private.h"
Packit ae235b
#endif
Packit ae235b
Packit ae235b
/* GResource functions {{{1 */
Packit ae235b
static GResource *
Packit ae235b
get_resource (const gchar *file)
Packit ae235b
{
Packit ae235b
  gchar *content;
Packit ae235b
  gsize size;
Packit ae235b
  GResource *resource;
Packit ae235b
  GBytes *data;
Packit ae235b
Packit ae235b
  resource = NULL;
Packit ae235b
Packit ae235b
  if (g_file_get_contents (file, &content, &size, NULL))
Packit ae235b
    {
Packit ae235b
      data = g_bytes_new_take (content, size);
Packit ae235b
      resource = g_resource_new_from_data (data, NULL);
Packit ae235b
      g_bytes_unref (data);
Packit ae235b
    }
Packit ae235b
Packit ae235b
  return resource;
Packit ae235b
}
Packit ae235b
Packit ae235b
static void
Packit ae235b
list_resource (GResource   *resource,
Packit ae235b
               const gchar *path,
Packit ae235b
               const gchar *section,
Packit ae235b
               const gchar *prefix,
Packit ae235b
               gboolean     details)
Packit ae235b
{
Packit ae235b
  gchar **children;
Packit ae235b
  gsize size;
Packit ae235b
  guint32 flags;
Packit ae235b
  gint i;
Packit ae235b
  gchar *child;
Packit ae235b
  GError *error = NULL;
Packit ae235b
  gint len;
Packit ae235b
Packit ae235b
  children = g_resource_enumerate_children (resource, path, 0, &error);
Packit ae235b
  if (error)
Packit ae235b
    {
Packit ae235b
      g_printerr ("%s\n", error->message);
Packit ae235b
      g_error_free (error);
Packit ae235b
      return;
Packit ae235b
    }
Packit ae235b
  for (i = 0; children[i]; i++)
Packit ae235b
    {
Packit ae235b
      child = g_strconcat (path, children[i], NULL);
Packit ae235b
Packit ae235b
      len = MIN (strlen (child), strlen (prefix));
Packit ae235b
      if (strncmp (child, prefix, len) != 0)
Packit ae235b
        {
Packit ae235b
          g_free (child);
Packit ae235b
          continue;
Packit ae235b
        }
Packit ae235b
Packit ae235b
      if (g_resource_get_info (resource, child, 0, &size, &flags, NULL))
Packit ae235b
        {
Packit ae235b
          if (details)
Packit ae235b
            g_print ("%s%s%6"G_GSIZE_FORMAT " %s %s\n", section, section[0] ? " " : "", size, (flags & G_RESOURCE_FLAGS_COMPRESSED) ? "c" : "u", child);
Packit ae235b
          else
Packit ae235b
            g_print ("%s\n", child);
Packit ae235b
        }
Packit ae235b
      else
Packit ae235b
        list_resource (resource, child, section, prefix, details);
Packit ae235b
Packit ae235b
      g_free (child);
Packit ae235b
    }
Packit ae235b
  g_strfreev (children);
Packit ae235b
}
Packit ae235b
Packit ae235b
static void
Packit ae235b
extract_resource (GResource   *resource,
Packit ae235b
                  const gchar *path)
Packit ae235b
{
Packit ae235b
  GBytes *bytes;
Packit ae235b
Packit ae235b
  bytes = g_resource_lookup_data (resource, path, 0, NULL);
Packit ae235b
  if (bytes != NULL)
Packit ae235b
    {
Packit ae235b
      gconstpointer data;
Packit ae235b
      gsize size, written;
Packit ae235b
Packit ae235b
      data = g_bytes_get_data (bytes, &size);
Packit ae235b
      written = fwrite (data, 1, size, stdout);
Packit ae235b
      if (written < size)
Packit ae235b
        g_printerr ("Data truncated\n");
Packit ae235b
      g_bytes_unref (bytes);
Packit ae235b
    }
Packit ae235b
}
Packit ae235b
Packit ae235b
/* Elf functions {{{1 */
Packit ae235b
Packit ae235b
#ifdef HAVE_LIBELF
Packit ae235b
Packit ae235b
static Elf *
Packit ae235b
get_elf (const gchar *file,
Packit ae235b
         gint        *fd)
Packit ae235b
{
Packit ae235b
  Elf *elf;
Packit ae235b
Packit ae235b
  if (elf_version (EV_CURRENT) == EV_NONE )
Packit ae235b
    return NULL;
Packit ae235b
Packit ae235b
  *fd = g_open (file, O_RDONLY, 0);
Packit ae235b
  if (*fd < 0)
Packit ae235b
    return NULL;
Packit ae235b
Packit ae235b
  elf = elf_begin (*fd, ELF_C_READ, NULL);
Packit ae235b
  if (elf == NULL)
Packit ae235b
    {
Packit ae235b
      g_close (*fd, NULL);
Packit ae235b
      *fd = -1;
Packit ae235b
      return NULL;
Packit ae235b
    }
Packit ae235b
Packit ae235b
  if (elf_kind (elf) != ELF_K_ELF)
Packit ae235b
    {
Packit ae235b
      g_close (*fd, NULL);
Packit ae235b
      *fd = -1;
Packit ae235b
      return NULL;
Packit ae235b
    }
Packit ae235b
Packit ae235b
  return elf;
Packit ae235b
}
Packit ae235b
Packit ae235b
typedef gboolean (*SectionCallback) (GElf_Shdr   *shdr,
Packit ae235b
                                     const gchar *name,
Packit ae235b
                                     gpointer     data);
Packit ae235b
Packit ae235b
static void
Packit ae235b
elf_foreach_resource_section (Elf             *elf,
Packit ae235b
                              SectionCallback  callback,
Packit ae235b
                              gpointer         data)
Packit ae235b
{
Packit ae235b
  size_t shstrndx, shnum;
Packit ae235b
  size_t scnidx;
Packit ae235b
  Elf_Scn *scn;
Packit ae235b
  GElf_Shdr *shdr, shdr_mem;
Packit ae235b
  const gchar *section_name;
Packit ae235b
Packit ae235b
  elf_getshdrstrndx (elf, &shstrndx);
Packit ae235b
  g_assert (shstrndx >= 0);
Packit ae235b
Packit ae235b
  elf_getshdrnum (elf, &shnum);
Packit ae235b
  g_assert (shnum >= 0);
Packit ae235b
Packit ae235b
  for (scnidx = 1; scnidx < shnum; scnidx++)
Packit ae235b
    {
Packit ae235b
      scn = elf_getscn (elf, scnidx);
Packit ae235b
      if (scn == NULL)
Packit ae235b
        continue;
Packit ae235b
Packit ae235b
      shdr = gelf_getshdr (scn, &shdr_mem);
Packit ae235b
      if (shdr == NULL)
Packit ae235b
        continue;
Packit ae235b
Packit ae235b
      if (shdr->sh_type != SHT_PROGBITS)
Packit ae235b
        continue;
Packit ae235b
Packit ae235b
      section_name = elf_strptr (elf, shstrndx, shdr->sh_name);
Packit ae235b
      if (section_name == NULL ||
Packit ae235b
          !g_str_has_prefix (section_name, ".gresource."))
Packit ae235b
        continue;
Packit ae235b
Packit ae235b
      if (!callback (shdr, section_name + strlen (".gresource."), data))
Packit ae235b
        break;
Packit ae235b
    }
Packit ae235b
}
Packit ae235b
Packit ae235b
static GResource *
Packit ae235b
resource_from_section (GElf_Shdr *shdr,
Packit ae235b
                       int        fd)
Packit ae235b
{
Packit ae235b
  gsize page_size, page_offset;
Packit ae235b
  char *contents;
Packit ae235b
  GResource *resource;
Packit ae235b
Packit ae235b
  resource = NULL;
Packit ae235b
Packit ae235b
  page_size = sysconf(_SC_PAGE_SIZE);
Packit ae235b
  page_offset = shdr->sh_offset % page_size;
Packit ae235b
  contents = mmap (NULL,  shdr->sh_size + page_offset,
Packit ae235b
                   PROT_READ, MAP_PRIVATE, fd, shdr->sh_offset - page_offset);
Packit ae235b
  if (contents != MAP_FAILED)
Packit ae235b
    {
Packit ae235b
      GBytes *bytes;
Packit ae235b
      GError *error = NULL;
Packit ae235b
Packit ae235b
      bytes = g_bytes_new_static (contents + page_offset, shdr->sh_size);
Packit ae235b
      resource = g_resource_new_from_data (bytes, &error);
Packit ae235b
      g_bytes_unref (bytes);
Packit ae235b
      if (error)
Packit ae235b
        {
Packit ae235b
          g_printerr ("%s\n", error->message);
Packit ae235b
          g_error_free (error);
Packit ae235b
        }
Packit ae235b
    }
Packit ae235b
  else
Packit ae235b
    {
Packit ae235b
      g_printerr ("Can't mmap resource section");
Packit ae235b
    }
Packit ae235b
Packit ae235b
  return resource;
Packit ae235b
}
Packit ae235b
Packit ae235b
typedef struct
Packit ae235b
{
Packit ae235b
  int fd;
Packit ae235b
  const gchar *section;
Packit ae235b
  const gchar *path;
Packit ae235b
  gboolean details;
Packit ae235b
  gboolean found;
Packit ae235b
} CallbackData;
Packit ae235b
Packit ae235b
static gboolean
Packit ae235b
list_resources_cb (GElf_Shdr   *shdr,
Packit ae235b
                   const gchar *section,
Packit ae235b
                   gpointer     data)
Packit ae235b
{
Packit ae235b
  CallbackData *d = data;
Packit ae235b
  GResource *resource;
Packit ae235b
Packit ae235b
  if (d->section && strcmp (section, d->section) != 0)
Packit ae235b
    return TRUE;
Packit ae235b
Packit ae235b
  d->found = TRUE;
Packit ae235b
Packit ae235b
  resource = resource_from_section (shdr, d->fd);
Packit ae235b
  list_resource (resource, "/",
Packit ae235b
                 d->section ? "" : section,
Packit ae235b
                 d->path,
Packit ae235b
                 d->details);
Packit ae235b
  g_resource_unref (resource);
Packit ae235b
Packit ae235b
  if (d->section)
Packit ae235b
    return FALSE;
Packit ae235b
Packit ae235b
  return TRUE;
Packit ae235b
}
Packit ae235b
Packit ae235b
static void
Packit ae235b
elf_list_resources (Elf         *elf,
Packit ae235b
                    int          fd,
Packit ae235b
                    const gchar *section,
Packit ae235b
                    const gchar *path,
Packit ae235b
                    gboolean     details)
Packit ae235b
{
Packit ae235b
  CallbackData data;
Packit ae235b
Packit ae235b
  data.fd = fd;
Packit ae235b
  data.section = section;
Packit ae235b
  data.path = path;
Packit ae235b
  data.details = details;
Packit ae235b
  data.found = FALSE;
Packit ae235b
Packit ae235b
  elf_foreach_resource_section (elf, list_resources_cb, &data);
Packit ae235b
Packit ae235b
  if (!data.found)
Packit ae235b
    g_printerr ("Can't find resource section %s\n", section);
Packit ae235b
}
Packit ae235b
Packit ae235b
static gboolean
Packit ae235b
extract_resource_cb (GElf_Shdr   *shdr,
Packit ae235b
                     const gchar *section,
Packit ae235b
                     gpointer     data)
Packit ae235b
{
Packit ae235b
  CallbackData *d = data;
Packit ae235b
  GResource *resource;
Packit ae235b
Packit ae235b
  if (d->section && strcmp (section, d->section) != 0)
Packit ae235b
    return TRUE;
Packit ae235b
Packit ae235b
  d->found = TRUE;
Packit ae235b
Packit ae235b
  resource = resource_from_section (shdr, d->fd);
Packit ae235b
  extract_resource (resource, d->path);
Packit ae235b
  g_resource_unref (resource);
Packit ae235b
Packit ae235b
  if (d->section)
Packit ae235b
    return FALSE;
Packit ae235b
Packit ae235b
  return TRUE;
Packit ae235b
}
Packit ae235b
Packit ae235b
static void
Packit ae235b
elf_extract_resource (Elf         *elf,
Packit ae235b
                      int          fd,
Packit ae235b
                      const gchar *section,
Packit ae235b
                      const gchar *path)
Packit ae235b
{
Packit ae235b
  CallbackData data;
Packit ae235b
Packit ae235b
  data.fd = fd;
Packit ae235b
  data.section = section;
Packit ae235b
  data.path = path;
Packit ae235b
  data.found = FALSE;
Packit ae235b
Packit ae235b
  elf_foreach_resource_section (elf, extract_resource_cb, &data);
Packit ae235b
Packit ae235b
  if (!data.found)
Packit ae235b
    g_printerr ("Can't find resource section %s\n", section);
Packit ae235b
}
Packit ae235b
Packit ae235b
static gboolean
Packit ae235b
print_section_name (GElf_Shdr   *shdr,
Packit ae235b
                    const gchar *name,
Packit ae235b
                    gpointer     data)
Packit ae235b
{
Packit ae235b
  g_print ("%s\n", name);
Packit ae235b
  return TRUE;
Packit ae235b
}
Packit ae235b
Packit ae235b
#endif /* HAVE_LIBELF */
Packit ae235b
Packit ae235b
  /* Toplevel commands {{{1 */
Packit ae235b
Packit ae235b
static void
Packit ae235b
cmd_sections (const gchar *file,
Packit ae235b
              const gchar *section,
Packit ae235b
              const gchar *path,
Packit ae235b
              gboolean     details)
Packit ae235b
{
Packit ae235b
  GResource *resource;
Packit ae235b
Packit ae235b
#ifdef HAVE_LIBELF
Packit ae235b
Packit ae235b
  Elf *elf;
Packit ae235b
  gint fd;
Packit ae235b
Packit ae235b
  if ((elf = get_elf (file, &fd)))
Packit ae235b
    {
Packit ae235b
      elf_foreach_resource_section (elf, print_section_name, NULL);
Packit ae235b
      elf_end (elf);
Packit ae235b
      close (fd);
Packit ae235b
    }
Packit ae235b
  else
Packit ae235b
Packit ae235b
#endif
Packit ae235b
Packit ae235b
  if ((resource = get_resource (file)))
Packit ae235b
    {
Packit ae235b
      /* No sections */
Packit ae235b
      g_resource_unref (resource);
Packit ae235b
    }
Packit ae235b
  else
Packit ae235b
    {
Packit ae235b
      g_printerr ("Don't know how to handle %s\n", file);
Packit ae235b
#ifndef HAVE_LIBELF
Packit ae235b
      g_printerr ("gresource is built without elf support\n");
Packit ae235b
#endif
Packit ae235b
    }
Packit ae235b
}
Packit ae235b
Packit ae235b
static void
Packit ae235b
cmd_list (const gchar *file,
Packit ae235b
          const gchar *section,
Packit ae235b
          const gchar *path,
Packit ae235b
          gboolean     details)
Packit ae235b
{
Packit ae235b
  GResource *resource;
Packit ae235b
Packit ae235b
#ifdef HAVE_LIBELF
Packit ae235b
  Elf *elf;
Packit ae235b
  int fd;
Packit ae235b
Packit ae235b
  if ((elf = get_elf (file, &fd)))
Packit ae235b
    {
Packit ae235b
      elf_list_resources (elf, fd, section, path ? path : "", details);
Packit ae235b
      elf_end (elf);
Packit ae235b
      close (fd);
Packit ae235b
    }
Packit ae235b
  else
Packit ae235b
Packit ae235b
#endif
Packit ae235b
Packit ae235b
  if ((resource = get_resource (file)))
Packit ae235b
    {
Packit ae235b
      list_resource (resource, "/", "", path ? path : "", details);
Packit ae235b
      g_resource_unref (resource);
Packit ae235b
    }
Packit ae235b
  else
Packit ae235b
    {
Packit ae235b
      g_printerr ("Don't know how to handle %s\n", file);
Packit ae235b
#ifndef HAVE_LIBELF
Packit ae235b
      g_printerr ("gresource is built without elf support\n");
Packit ae235b
#endif
Packit ae235b
    }
Packit ae235b
}
Packit ae235b
Packit ae235b
static void
Packit ae235b
cmd_extract (const gchar *file,
Packit ae235b
             const gchar *section,
Packit ae235b
             const gchar *path,
Packit ae235b
             gboolean     details)
Packit ae235b
{
Packit ae235b
  GResource *resource;
Packit ae235b
Packit ae235b
#ifdef HAVE_LIBELF
Packit ae235b
Packit ae235b
  Elf *elf;
Packit ae235b
  int fd;
Packit ae235b
Packit ae235b
  if ((elf = get_elf (file, &fd)))
Packit ae235b
    {
Packit ae235b
      elf_extract_resource (elf, fd, section, path);
Packit ae235b
      elf_end (elf);
Packit ae235b
      close (fd);
Packit ae235b
    }
Packit ae235b
  else
Packit ae235b
Packit ae235b
#endif
Packit ae235b
Packit ae235b
  if ((resource = get_resource (file)))
Packit ae235b
    {
Packit ae235b
      extract_resource (resource, path);
Packit ae235b
      g_resource_unref (resource);
Packit ae235b
    }
Packit ae235b
  else
Packit ae235b
    {
Packit ae235b
      g_printerr ("Don't know how to handle %s\n", file);
Packit ae235b
#ifndef HAVE_LIBELF
Packit ae235b
      g_printerr ("gresource is built without elf support\n");
Packit ae235b
#endif
Packit ae235b
    }
Packit ae235b
}
Packit ae235b
Packit ae235b
static gint
Packit ae235b
cmd_help (gboolean     requested,
Packit ae235b
          const gchar *command)
Packit ae235b
{
Packit ae235b
  const gchar *description;
Packit ae235b
  const gchar *synopsis;
Packit ae235b
  gchar *option;
Packit ae235b
  GString *string;
Packit ae235b
Packit ae235b
  option = NULL;
Packit ae235b
Packit ae235b
  string = g_string_new (NULL);
Packit ae235b
Packit ae235b
  if (command == NULL)
Packit ae235b
    ;
Packit ae235b
Packit ae235b
  else if (strcmp (command, "help") == 0)
Packit ae235b
    {
Packit ae235b
      description = _("Print help");
Packit ae235b
      synopsis = _("[COMMAND]");
Packit ae235b
    }
Packit ae235b
Packit ae235b
  else if (strcmp (command, "sections") == 0)
Packit ae235b
    {
Packit ae235b
      description = _("List sections containing resources in an elf FILE");
Packit ae235b
      synopsis = _("FILE");
Packit ae235b
    }
Packit ae235b
Packit ae235b
  else if (strcmp (command, "list") == 0)
Packit ae235b
    {
Packit ae235b
      description = _("List resources\n"
Packit ae235b
                      "If SECTION is given, only list resources in this section\n"
Packit ae235b
                      "If PATH is given, only list matching resources");
Packit ae235b
      synopsis = _("FILE [PATH]");
Packit ae235b
      option = g_strdup_printf ("[--section %s]", _("SECTION"));
Packit ae235b
    }
Packit ae235b
Packit ae235b
  else if (strcmp (command, "details") == 0)
Packit ae235b
    {
Packit ae235b
      description = _("List resources with details\n"
Packit ae235b
                      "If SECTION is given, only list resources in this section\n"
Packit ae235b
                      "If PATH is given, only list matching resources\n"
Packit ae235b
                      "Details include the section, size and compression");
Packit ae235b
      synopsis = _("FILE [PATH]");
Packit ae235b
      option = g_strdup_printf ("[--section %s]", _("SECTION"));
Packit ae235b
    }
Packit ae235b
Packit ae235b
  else if (strcmp (command, "extract") == 0)
Packit ae235b
    {
Packit ae235b
      description = _("Extract a resource file to stdout");
Packit ae235b
      synopsis = _("FILE PATH");
Packit ae235b
      option = g_strdup_printf ("[--section %s]", _("SECTION"));
Packit ae235b
    }
Packit ae235b
Packit ae235b
  else
Packit ae235b
    {
Packit ae235b
      g_string_printf (string, _("Unknown command %s\n\n"), command);
Packit ae235b
      requested = FALSE;
Packit ae235b
      command = NULL;
Packit ae235b
    }
Packit ae235b
Packit ae235b
  if (command == NULL)
Packit ae235b
    {
Packit ae235b
      g_string_append (string,
Packit ae235b
      _("Usage:\n"
Packit ae235b
        "  gresource [--section SECTION] COMMAND [ARGS…]\n"
Packit ae235b
        "\n"
Packit ae235b
        "Commands:\n"
Packit ae235b
        "  help                      Show this information\n"
Packit ae235b
        "  sections                  List resource sections\n"
Packit ae235b
        "  list                      List resources\n"
Packit ae235b
        "  details                   List resources with details\n"
Packit ae235b
        "  extract                   Extract a resource\n"
Packit ae235b
        "\n"
Packit ae235b
        "Use “gresource help COMMAND” to get detailed help.\n\n"));
Packit ae235b
    }
Packit ae235b
  else
Packit ae235b
    {
Packit ae235b
      g_string_append_printf (string, _("Usage:\n  gresource %s%s%s %s\n\n%s\n\n"),
Packit ae235b
                              option ? option : "", option ? " " : "", command, synopsis[0] ? synopsis : "", description);
Packit ae235b
Packit ae235b
      g_string_append (string, _("Arguments:\n"));
Packit ae235b
Packit ae235b
      if (option)
Packit ae235b
        g_string_append (string,
Packit ae235b
                         _("  SECTION   An (optional) elf section name\n"));
Packit ae235b
Packit ae235b
      if (strstr (synopsis, _("[COMMAND]")))
Packit ae235b
        g_string_append (string,
Packit ae235b
                       _("  COMMAND   The (optional) command to explain\n"));
Packit ae235b
Packit ae235b
      if (strstr (synopsis, _("FILE")))
Packit ae235b
        {
Packit ae235b
          if (strcmp (command, "sections") == 0)
Packit ae235b
            g_string_append (string,
Packit ae235b
                             _("  FILE      An elf file (a binary or a shared library)\n"));
Packit ae235b
          else
Packit ae235b
            g_string_append (string,
Packit ae235b
                             _("  FILE      An elf file (a binary or a shared library)\n"
Packit ae235b
                               "            or a compiled resource file\n"));
Packit ae235b
        }
Packit ae235b
Packit ae235b
      if (strstr (synopsis, _("[PATH]")))
Packit ae235b
        g_string_append (string,
Packit ae235b
                       _("  PATH      An (optional) resource path (may be partial)\n"));
Packit ae235b
      else if (strstr (synopsis, _("PATH")))
Packit ae235b
        g_string_append (string,
Packit ae235b
                       _("  PATH      A resource path\n"));
Packit ae235b
Packit ae235b
      g_string_append (string, "\n");
Packit ae235b
    }
Packit ae235b
Packit ae235b
  if (requested)
Packit ae235b
    g_print ("%s", string->str);
Packit ae235b
  else
Packit ae235b
    g_printerr ("%s\n", string->str);
Packit ae235b
Packit ae235b
  g_free (option);
Packit ae235b
  g_string_free (string, TRUE);
Packit ae235b
Packit ae235b
  return requested ? 0 : 1;
Packit ae235b
}
Packit ae235b
Packit ae235b
/* main {{{1 */
Packit ae235b
Packit ae235b
int
Packit ae235b
main (int argc, char *argv[])
Packit ae235b
{
Packit ae235b
  gchar *section = NULL;
Packit ae235b
  gboolean details = FALSE;
Packit ae235b
  void (* function) (const gchar *, const gchar *, const gchar *, gboolean);
Packit ae235b
Packit ae235b
#ifdef G_OS_WIN32
Packit ae235b
  gchar *tmp;
Packit ae235b
#endif
Packit ae235b
Packit ae235b
  setlocale (LC_ALL, "");
Packit ae235b
  textdomain (GETTEXT_PACKAGE);
Packit ae235b
Packit ae235b
#ifdef G_OS_WIN32
Packit ae235b
  tmp = _glib_get_locale_dir ();
Packit ae235b
  bindtextdomain (GETTEXT_PACKAGE, tmp);
Packit ae235b
  g_free (tmp);
Packit ae235b
#else
Packit ae235b
  bindtextdomain (GETTEXT_PACKAGE, GLIB_LOCALE_DIR);
Packit ae235b
#endif
Packit ae235b
Packit ae235b
#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
Packit ae235b
  bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
Packit ae235b
#endif
Packit ae235b
Packit ae235b
  if (argc < 2)
Packit ae235b
    return cmd_help (FALSE, NULL);
Packit ae235b
Packit ae235b
  if (argc > 3 && strcmp (argv[1], "--section") == 0)
Packit ae235b
    {
Packit ae235b
      section = argv[2];
Packit ae235b
      argv = argv + 2;
Packit ae235b
      argc -= 2;
Packit ae235b
    }
Packit ae235b
Packit ae235b
  if (strcmp (argv[1], "help") == 0)
Packit ae235b
    return cmd_help (TRUE, argv[2]);
Packit ae235b
Packit ae235b
  else if (argc == 4 && strcmp (argv[1], "extract") == 0)
Packit ae235b
    function = cmd_extract;
Packit ae235b
Packit ae235b
  else if (argc == 3 && strcmp (argv[1], "sections") == 0)
Packit ae235b
    function = cmd_sections;
Packit ae235b
Packit ae235b
  else if ((argc == 3 || argc == 4) && strcmp (argv[1], "list") == 0)
Packit ae235b
    {
Packit ae235b
      function = cmd_list;
Packit ae235b
      details = FALSE;
Packit ae235b
    }
Packit ae235b
  else if ((argc == 3 || argc == 4) && strcmp (argv[1], "details") == 0)
Packit ae235b
    {
Packit ae235b
      function = cmd_list;
Packit ae235b
      details = TRUE;
Packit ae235b
    }
Packit ae235b
  else
Packit ae235b
    return cmd_help (FALSE, argv[1]);
Packit ae235b
Packit ae235b
  (* function) (argv[2], section, argc > 3 ? argv[3] : NULL, details);
Packit ae235b
Packit ae235b
  return 0;
Packit ae235b
}
Packit ae235b
Packit ae235b
/* vim:set foldmethod=marker: */