/* touch.c
 *
 ****************************************************************
 * Copyright (C) 2001, 2002, 2003, 2005  Free Software Foundation, Inc.
 *
 * See the file "COPYING" for further information about
 * the copyright and warranty status of this work.
 */


#include "config-options.h"
#include "hackerlab/cmd/main.h"
#include "tla/libarch/changelogs.h"
#include "tla/libarch/inv-ids.h"
#include "tla/libarch/cmd.h"
#include "tla/libarch/cmd-touch.h"



static t_uchar * usage = "[options] file ...";
static t_uchar * version_string = (cfg__std__package " from regexps.com\n"
                                   "\n"
                                   "Copyright 2001, 2002, 2003, 2005 Free Software Foundation, Inc.\n"
                                   "\n"
                                   "This is free software; see the source for copying conditions.\n"
                                   "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A\n"
                                   "PARTICULAR PURPOSE.\n"
                                   "\n"
                                   "Report bugs to " cfg__tla_bug_mail ".\n"
                                   "\n"
                                   cfg__std__release_id_string
                                   "\n");

#define OPTS(OP) \
  OP (opt_help_msg, "h", "help", 0, \
      "Display a help message and exit.") \
  OP (opt_long_help, "H", 0, 0, \
      "Display a verbose help message and exit.") \
  OP (opt_version, "V", "version", 0, \
      "Display a release identifier string\n" \
      "and exit.") \
  OP (opt_id, "i", "id ID", 1, \
      "Specify ID, instead of using auto-generated id.")

t_uchar arch_cmd_touch_help[] = ("add an explicit inventory id, touching the file.\n"
                                 "Create an explicit inventory id for FILE (which may be a\n"
                                 "regular file, symbolic link, or directory).\n"
                                 "This command also sets the modification and access times\n"
				 "of the file, creating it if necessary.\n");


enum options
{
  OPTS (OPT_ENUM)
};

static struct opt_desc opts[] =
{
  OPTS (OPT_DESC)
    {-1, 0, 0, 0, 0}
};



int
arch_cmd_touch (t_uchar *program_name, int argc, char * argv[])
{
  int o;
  struct opt_parsed * option;
  char * id = 0;

  safe_buffer_fd (1, 0, O_WRONLY, 0);

  option = 0;

  while (1)
    {
      o = opt_standard (lim_use_must_malloc, &option, opts, &argc, argv, program_name, usage, version_string, arch_cmd_touch_help, opt_help_msg, opt_long_help, opt_version);
      if (o == opt_none)
        break;
      switch (o)
        {
        default:
          safe_printfmt (2, "unhandled option `%s'\n", option->opt_string);
          panic ("internal error parsing arguments");

        usage_error:
          opt_usage (2, argv[0], program_name, usage, 1);
          exit (1);

          /* bogus_arg: */
          safe_printfmt (2, "ill-formed argument for `%s' (`%s')\n", option->opt_string, option->arg_string);
          goto usage_error;

        case opt_id:
          {
            id = str_save(0, option->arg_string);
            break;
          }
        }
    }

  if (argc < 2)
    goto usage_error;

  {
    int a;

    for (a = 1; a < argc; ++a)
      {
        t_uchar * file;
        t_uchar * tagline_id;
        t_uchar * new_explicit_id;
        int use_utimes;

        file = argv[a];

        if (!safe_access (file, F_OK))
          {
            tagline_id = arch_inventory_id (arch_tagline_id_tagging, 0, file, 0, 0, 0);
            use_utimes = 1;
          }
        else
          {
            tagline_id = 0;
            use_utimes = 0;
          }

        if (!tagline_id || !arch_id_indicates_changelog (tagline_id))
          if (!id)
            new_explicit_id = arch_generate_id ();
          else
            new_explicit_id = id;
        else
          new_explicit_id = str_save (0, 2 + tagline_id);

        arch_add_explicit_id (file, new_explicit_id);

        if (use_utimes)
          {
            utimes (file, 0);
          }
        else
          {
            int fd;
            fd = safe_open (file, O_WRONLY | O_CREAT, 0777);
            safe_close (fd);
          }
        

        lim_free (0, new_explicit_id);
        lim_free (0, tagline_id);
      }
  }


  return 0;
}



/* tag: Tom Lord Sun Mar 20 17:51:55 2005 (libarch/cmd-touch.c)
 */
