mirror of
https://github.com/moparisthebest/curl
synced 2024-11-11 20:15:03 -05:00
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).
This commit is contained in:
parent
1786950759
commit
fbf51696ef
@ -15,11 +15,12 @@ CURLX_ONES = $(top_srcdir)/lib/strtoofft.c \
|
|||||||
$(top_srcdir)/lib/nonblock.c
|
$(top_srcdir)/lib/nonblock.c
|
||||||
|
|
||||||
CURL_CFILES = main.c hugehelp.c urlglob.c writeout.c writeenv.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 \
|
CURL_HFILES = hugehelp.h setup.h config-win32.h config-mac.h \
|
||||||
config-riscos.h urlglob.h version.h os-specific.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)
|
curl_SOURCES = $(CURL_CFILES) $(CURLX_ONES) $(CURL_HFILES)
|
||||||
|
|
||||||
|
17
src/main.c
17
src/main.c
@ -51,6 +51,8 @@
|
|||||||
#endif
|
#endif
|
||||||
#include "rawstr.h"
|
#include "rawstr.h"
|
||||||
|
|
||||||
|
#include "xattr.h"
|
||||||
|
|
||||||
#define CURLseparator "--_curl_--"
|
#define CURLseparator "--_curl_--"
|
||||||
|
|
||||||
#ifdef NETWARE
|
#ifdef NETWARE
|
||||||
@ -621,6 +623,7 @@ struct Configurable {
|
|||||||
int default_node_flags; /* default flags to seach for each 'node', which is
|
int default_node_flags; /* default flags to seach for each 'node', which is
|
||||||
basically each given URL to transfer */
|
basically each given URL to transfer */
|
||||||
struct OutStruct *outs;
|
struct OutStruct *outs;
|
||||||
|
bool xattr; /* store metadata in extended attributes */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define WARN_PREFIX "Warning: "
|
#define WARN_PREFIX "Warning: "
|
||||||
@ -906,6 +909,7 @@ static void help(void)
|
|||||||
" --wdebug Turn on Watt-32 debugging",
|
" --wdebug Turn on Watt-32 debugging",
|
||||||
#endif
|
#endif
|
||||||
" -w/--write-out <format> What to output after completion",
|
" -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",
|
" -q If used as the first parameter disables .curlrc",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
@ -1953,6 +1957,7 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
|
|||||||
{"y", "speed-time", TRUE},
|
{"y", "speed-time", TRUE},
|
||||||
{"z", "time-cond", TRUE},
|
{"z", "time-cond", TRUE},
|
||||||
{"#", "progress-bar",FALSE},
|
{"#", "progress-bar",FALSE},
|
||||||
|
{"~", "xattr",FALSE},
|
||||||
};
|
};
|
||||||
|
|
||||||
if(('-' != flag[0]) ||
|
if(('-' != flag[0]) ||
|
||||||
@ -2445,6 +2450,9 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
|
|||||||
else
|
else
|
||||||
config->progressmode = CURL_PROGRESS_STATS;
|
config->progressmode = CURL_PROGRESS_STATS;
|
||||||
break;
|
break;
|
||||||
|
case '~': /* --xattr */
|
||||||
|
config->xattr = toggle;
|
||||||
|
break;
|
||||||
case '0':
|
case '0':
|
||||||
/* HTTP version 1.0 */
|
/* HTTP version 1.0 */
|
||||||
config->httpversion = CURL_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
|
#ifdef HAVE_UTIME
|
||||||
/* Important that we set the time _after_ the file has been
|
/* Important that we set the time _after_ the file has been
|
||||||
closed, as is done above here */
|
closed, as is done above here */
|
||||||
|
37
src/xattr.c
Normal file
37
src/xattr.c
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#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;
|
||||||
|
}
|
1
src/xattr.h
Normal file
1
src/xattr.h
Normal file
@ -0,0 +1 @@
|
|||||||
|
int write_xattr( CURL *curl, const char *filename );
|
Loading…
Reference in New Issue
Block a user