Public feed #721943

Someone

public text v1 · immutable
Raw Edit
·published 2007-10-01 17:32 UTC
rendered paste body
#include <config.h>

#include <stdio.h>
#include <unistd.h>
#include <locale.h>
#include <errno.h>
#include <string.h>

#include <glib.h>
#include <gio/gfile.h>

static gboolean only_access = FALSE;
static gboolean only_modification = FALSE;
static gboolean do_access = FALSE;
static gboolean do_modification = FALSE;
static gboolean no_create = FALSE;

static GOptionEntry entries[] = 
{
  { "access", 'a', 0, G_OPTION_ARG_NONE, &only_access, "change access time", NULL },
  { "modification", 'm', 0, G_OPTION_ARG_NONE, &only_modification, "change modification time", NULL },
  { "no-create", 'c', 0, G_OPTION_ARG_NONE, &no_create, "do not create file if it doesn't exist", NULL },
  { NULL }
};

static void
touch (GFile *file)
{
  GFileInfo *info;
  GError *error = NULL;
  GFileAttributeMatcher *mask;
  GTimeVal now;
  gboolean res;

  info = g_file_query_info (file, "time:*", 0, NULL, &error);

  if (info == NULL)
    {

      /* FIXME: This was confusing... I expected G_FILE_ERROR... should we
         use that domain. Even if not G_IO_ERROR_NOT_FOUND is not consistent
         with G_FILE_ERROR_NOENT */

      if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND) &&
          !no_create)
        {
          g_clear_error (&error);
          g_file_create (file, 0, NULL, &error);
          if (error)
            {
              g_printerr ("Error creating file: %s\n", error->message);
              g_error_free (error);
              return;
            }

            info = g_file_info_new ();
        }
      else
        {
          g_printerr ("Error getting info: %s\n", error->message);
          g_error_free (error);
          return;
        }
    }

  mask = g_file_attribute_matcher_new (G_FILE_ATTRIBUTE_TIME_MODIFIED ","
                                       G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC ","
                                       G_FILE_ATTRIBUTE_TIME_ACCESS ","
                                       G_FILE_ATTRIBUTE_TIME_ACCESS_USEC);

  g_file_info_set_attribute_mask (info, mask);

  g_get_current_time (&now);

  if (do_modification)
    g_file_info_set_modification_time (info, &now);

  if (do_access)
    g_printerr ("g_file_info_set_acess_time not implemented!\n");
    /* g_file_info_set_acess_time (info, &now); */

  res = g_file_set_attributes_from_info (file, info, 0, NULL, &error);

  if (!res)
    {
      g_printerr ("Error setting info: %s\n", error->message);
      g_error_free (error);
      return;
    }
}

int
main (int argc, char *argv[])
{
  GError *error;
  GOptionContext *context;
  int i;

  setlocale (LC_ALL, "");

  g_type_init ();
  
  error = NULL;
  context = g_option_context_new ("- touch files at <location>");
  g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
  g_option_context_parse (context, &argc, &argv, &error);

  if (argc <= 1)
    {
      g_printerr ("Missing operand\n");
      return 1;
    }

  /* if both -a and -m are specified or none of them is specified
     update both times, otherwise just the specified one */
  if (only_access == only_modification)
    {
      do_access = do_modification = TRUE;
    }
  else
    {
      do_access = only_access;
      do_modification = only_modification;
    }

  for (i = 1; i < argc; i++)
    {
      GFile *file;

      file = g_file_new_for_commandline_arg (argv[i]);
      touch (file);
      g_object_unref (file);
    }

  return 0;
}