Commit fbf51696 authored by Stefan Tomanek's avatar Stefan Tomanek Committed by Daniel Stenberg
Browse files

save metadata to extended file attributes

It is often convinient to track back the source of a once downloaded
file; this patch makes curl store the source URL and other metadata
alongside the retrieved file by using the extended attributes (if
supported by the file system and enabled by --xattr).
parent 17869507
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -15,11 +15,12 @@ CURLX_ONES = $(top_srcdir)/lib/strtoofft.c \
	$(top_srcdir)/lib/nonblock.c

CURL_CFILES = main.c hugehelp.c urlglob.c writeout.c writeenv.c \
	getpass.c homedir.c curlutil.c os-specific.c
	getpass.c homedir.c curlutil.c os-specific.c xattr.c

CURL_HFILES = hugehelp.h setup.h config-win32.h config-mac.h \
	config-riscos.h urlglob.h version.h os-specific.h \
	writeout.h writeenv.h getpass.h homedir.h curlutil.h
	writeout.h writeenv.h getpass.h homedir.h curlutil.h \
	xattr.h

curl_SOURCES = $(CURL_CFILES) $(CURLX_ONES) $(CURL_HFILES)
+17 −0
Original line number Diff line number Diff line
@@ -51,6 +51,8 @@
#endif
#include "rawstr.h"

#include "xattr.h"

#define CURLseparator   "--_curl_--"

#ifdef NETWARE
@@ -621,6 +623,7 @@ struct Configurable {
  int default_node_flags; /* default flags to seach for each 'node', which is
                             basically each given URL to transfer */
  struct OutStruct *outs;
  bool xattr; /* store metadata in extended attributes */
};

#define WARN_PREFIX "Warning: "
@@ -906,6 +909,7 @@ static void help(void)
    "    --wdebug        Turn on Watt-32 debugging",
#endif
    " -w/--write-out <format> What to output after completion",
    " --xattr            Store metadata in extended file attributes",
    " -q                 If used as the first parameter disables .curlrc",
    NULL
  };
@@ -1953,6 +1957,7 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
    {"y", "speed-time", TRUE},
    {"z", "time-cond",   TRUE},
    {"#", "progress-bar",FALSE},
    {"~", "xattr",FALSE},
  };

  if(('-' != flag[0]) ||
@@ -2445,6 +2450,9 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
      else
        config->progressmode = CURL_PROGRESS_STATS;
      break;
    case '~': /* --xattr */
      config->xattr = toggle;
      break;
    case '0':
      /* HTTP version 1.0 */
      config->httpversion = CURL_HTTP_VERSION_1_0;
@@ -5639,6 +5647,15 @@ operate(struct Configurable *config, int argc, argv_item_t argv[])
          }
        }

        if(config->xattr && outs.filename) {
          char *url = NULL;
          curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &url);
          int err = write_xattr( curl, outs.filename );
          if (err) {
            warnf( config, "Error setting extended attributes: %s\n", strerror(errno) );
          }
        }

#ifdef HAVE_UTIME
        /* Important that we set the time _after_ the file has been
           closed, as is done above here */

src/xattr.c

0 → 100644
+37 −0
Original line number Diff line number Diff line
#include <sys/types.h>
#include <sys/xattr.h> /* include header from libc, not from libattr */
#include <string.h>
#include <curl/curl.h>
#include "xattr.h"

/* mapping table of curl metadata to extended attribute names */
static struct xattr_mapping {
  char *attr; /* name of the xattr */
  CURLINFO info;
} mappings[] = {
  /* mappings proposed by
   * http://freedesktop.org/wiki/CommonExtendedAttributes
   */
  { "user.xdg.origin.url", CURLINFO_EFFECTIVE_URL },
  { "user.mime_type", CURLINFO_CONTENT_TYPE },
  { NULL, 0 } /* last element, abort loop here */
};

/* store metadata from the curl request alongside the downloaded
 * file using extended attributes
 */
int write_xattr( CURL *curl, const char *filename )
{
  int i = 0;
  int err = 0;
  /* loop through all xattr-curlinfo pairs and abort on error */
  while ( err == 0 && mappings[i].attr != NULL ) {
    char *value = NULL;
    curl_easy_getinfo(curl, mappings[i].info, &value);
    if (value) {
      err = setxattr( filename, mappings[i].attr, value, strlen(value), 0 );
    }
    i++;
  }
  return err;
}

src/xattr.h

0 → 100644
+1 −0
Original line number Diff line number Diff line
int write_xattr( CURL *curl, const char *filename );