Blame debuginfod/debuginfod-find.c

Packit 032894
/* Command-line frontend for retrieving ELF / DWARF / source files
Packit 032894
   from the debuginfod.
Packit 032894
   Copyright (C) 2019 Red Hat, Inc.
Packit 032894
   This file is part of elfutils.
Packit 032894
Packit 032894
   This file is free software; you can redistribute it and/or modify
Packit 032894
   it under the terms of the GNU General Public License as published by
Packit 032894
   the Free Software Foundation; either version 3 of the License, or
Packit 032894
   (at your option) any later version.
Packit 032894
Packit 032894
   elfutils is distributed in the hope that it will be useful, but
Packit 032894
   WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 032894
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 032894
   General Public License for more details.
Packit 032894
Packit 032894
   You should have received copies of the GNU General Public License and
Packit 032894
   the GNU Lesser General Public License along with this program.  If
Packit 032894
   not, see <http://www.gnu.org/licenses/>.  */
Packit 032894
Packit 032894
#include "config.h"
Packit 032894
#include "printversion.h"
Packit 032894
#include "debuginfod.h"
Packit 032894
#include <errno.h>
Packit 032894
#include <stdio.h>
Packit 032894
#include <stdlib.h>
Packit 032894
#include <string.h>
Packit 032894
#include <argp.h>
Packit 032894
Packit 032894
Packit 032894
/* Name and version of program.  */
Packit 032894
ARGP_PROGRAM_VERSION_HOOK_DEF = print_version;
Packit 032894
Packit 032894
/* Bug report address.  */
Packit 032894
ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;
Packit 032894
Packit 032894
/* Short description of program.  */
Packit 032894
static const char doc[] = N_("Request debuginfo-related content "
Packit 032894
                             "from debuginfods listed in $" DEBUGINFOD_URLS_ENV_VAR ".");
Packit 032894
Packit 032894
/* Strings for arguments in help texts.  */
Packit 032894
static const char args_doc[] = N_("debuginfo BUILDID\n"
Packit 032894
                                  "executable BUILDID\n"
Packit 032894
                                  "source BUILDID /FILENAME");
Packit 032894
Packit 032894
/* Definitions of arguments for argp functions.  */
Packit 032894
static const struct argp_option options[] =
Packit 032894
  {
Packit 032894
   { "verbose", 'v', NULL, 0, "Increase verbosity.", 0 },
Packit 032894
   { NULL, 0, NULL, 0, NULL, 0 }
Packit 032894
  };
Packit 032894
Packit 032894
/* debuginfod connection handle.  */
Packit 032894
static debuginfod_client *client;
Packit 032894
Packit 032894
int progressfn(debuginfod_client *c __attribute__((__unused__)),
Packit 032894
	       long a, long b)
Packit 032894
{
Packit 032894
  fprintf (stderr, "Progress %ld / %ld\n", a, b);
Packit 032894
  return 0;
Packit 032894
}
Packit 032894
Packit 032894
Packit 032894
static error_t parse_opt (int key, char *arg, struct argp_state *state)
Packit 032894
{
Packit 032894
  (void) arg;
Packit 032894
  (void) state;
Packit 032894
  switch (key)
Packit 032894
    {
Packit 032894
    case 'v': debuginfod_set_progressfn (client, & progressfn); break;
Packit 032894
    default: return ARGP_ERR_UNKNOWN;
Packit 032894
    }
Packit 032894
  return 0;
Packit 032894
}
Packit 032894
Packit 032894
Packit 032894
/* Data structure to communicate with argp functions.  */
Packit 032894
static struct argp argp =
Packit 032894
  {
Packit 032894
   options, parse_opt, args_doc, doc, NULL, NULL, NULL
Packit 032894
  };
Packit 032894
Packit 032894
Packit 032894
Packit 032894
int
Packit 032894
main(int argc, char** argv)
Packit 032894
{
Packit 032894
  client = debuginfod_begin ();
Packit 032894
  if (client == NULL)
Packit 032894
    {
Packit 032894
      fprintf(stderr, "Couldn't create debuginfod client context\n");
Packit 032894
      return 1;
Packit 032894
    }
Packit 032894
Packit 032894
  int remaining;
Packit 032894
  (void) argp_parse (&argp, argc, argv, ARGP_IN_ORDER|ARGP_NO_ARGS, &remaining, NULL);
Packit 032894
Packit 032894
  if (argc < 2 || remaining+1 == argc) /* no arguments or at least two non-option words */
Packit 032894
    {
Packit 032894
      argp_help (&argp, stderr, ARGP_HELP_USAGE, argv[0]);
Packit 032894
      return 1;
Packit 032894
    }
Packit 032894
Packit 032894
  int rc;
Packit 032894
  char *cache_name;
Packit 032894
Packit 032894
  /* Check whether FILETYPE is valid and call the appropriate
Packit 032894
     debuginfod_find_* function. If FILETYPE is "source"
Packit 032894
     then ensure a FILENAME was also supplied as an argument.  */
Packit 032894
  if (strcmp(argv[remaining], "debuginfo") == 0)
Packit 032894
    rc = debuginfod_find_debuginfo(client,
Packit 032894
				   (unsigned char *)argv[remaining+1], 0,
Packit 032894
				   &cache_name);
Packit 032894
  else if (strcmp(argv[remaining], "executable") == 0)
Packit 032894
    rc = debuginfod_find_executable(client,
Packit 032894
				    (unsigned char *)argv[remaining+1], 0,
Packit 032894
				    &cache_name);
Packit 032894
  else if (strcmp(argv[remaining], "source") == 0)
Packit 032894
    {
Packit 032894
      if (remaining+2 == argc || argv[3][0] != '/')
Packit 032894
        {
Packit 032894
          fprintf(stderr, "If FILETYPE is \"source\" then absolute /FILENAME must be given\n");
Packit 032894
          return 1;
Packit 032894
        }
Packit 032894
      rc = debuginfod_find_source(client, (unsigned char *)argv[remaining+1],
Packit 032894
				  0, argv[remaining+2], &cache_name);
Packit 032894
    }
Packit 032894
  else
Packit 032894
    {
Packit 032894
      argp_help (&argp, stderr, ARGP_HELP_USAGE, argv[0]);
Packit 032894
      return 1;
Packit 032894
    }
Packit 032894
Packit 032894
  if (rc < 0)
Packit 032894
    {
Packit 032894
      fprintf(stderr, "Server query failed: %s\n", strerror(-rc));
Packit 032894
      return 1;
Packit 032894
    }
Packit 032894
Packit 032894
  printf("%s\n", cache_name);
Packit 032894
Packit 032894
  free (cache_name);
Packit 032894
  debuginfod_end (client);
Packit 032894
Packit 032894
  return 0;
Packit 032894
}