xref: /aosp_15_r20/external/curl/src/tool_xattr.c (revision 6236dae45794135f37c4eb022389c904c8b0090d)
1*6236dae4SAndroid Build Coastguard Worker /***************************************************************************
2*6236dae4SAndroid Build Coastguard Worker  *                                  _   _ ____  _
3*6236dae4SAndroid Build Coastguard Worker  *  Project                     ___| | | |  _ \| |
4*6236dae4SAndroid Build Coastguard Worker  *                             / __| | | | |_) | |
5*6236dae4SAndroid Build Coastguard Worker  *                            | (__| |_| |  _ <| |___
6*6236dae4SAndroid Build Coastguard Worker  *                             \___|\___/|_| \_\_____|
7*6236dae4SAndroid Build Coastguard Worker  *
8*6236dae4SAndroid Build Coastguard Worker  * Copyright (C) Daniel Stenberg, <[email protected]>, et al.
9*6236dae4SAndroid Build Coastguard Worker  *
10*6236dae4SAndroid Build Coastguard Worker  * This software is licensed as described in the file COPYING, which
11*6236dae4SAndroid Build Coastguard Worker  * you should have received as part of this distribution. The terms
12*6236dae4SAndroid Build Coastguard Worker  * are also available at https://curl.se/docs/copyright.html.
13*6236dae4SAndroid Build Coastguard Worker  *
14*6236dae4SAndroid Build Coastguard Worker  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15*6236dae4SAndroid Build Coastguard Worker  * copies of the Software, and permit persons to whom the Software is
16*6236dae4SAndroid Build Coastguard Worker  * furnished to do so, under the terms of the COPYING file.
17*6236dae4SAndroid Build Coastguard Worker  *
18*6236dae4SAndroid Build Coastguard Worker  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19*6236dae4SAndroid Build Coastguard Worker  * KIND, either express or implied.
20*6236dae4SAndroid Build Coastguard Worker  *
21*6236dae4SAndroid Build Coastguard Worker  * SPDX-License-Identifier: curl
22*6236dae4SAndroid Build Coastguard Worker  *
23*6236dae4SAndroid Build Coastguard Worker  ***************************************************************************/
24*6236dae4SAndroid Build Coastguard Worker #include "tool_setup.h"
25*6236dae4SAndroid Build Coastguard Worker #include "tool_xattr.h"
26*6236dae4SAndroid Build Coastguard Worker 
27*6236dae4SAndroid Build Coastguard Worker #include "memdebug.h" /* keep this as LAST include */
28*6236dae4SAndroid Build Coastguard Worker 
29*6236dae4SAndroid Build Coastguard Worker #ifdef USE_XATTR
30*6236dae4SAndroid Build Coastguard Worker 
31*6236dae4SAndroid Build Coastguard Worker /* mapping table of curl metadata to extended attribute names */
32*6236dae4SAndroid Build Coastguard Worker static const struct xattr_mapping {
33*6236dae4SAndroid Build Coastguard Worker   const char *attr; /* name of the xattr */
34*6236dae4SAndroid Build Coastguard Worker   CURLINFO info;
35*6236dae4SAndroid Build Coastguard Worker } mappings[] = {
36*6236dae4SAndroid Build Coastguard Worker   /* mappings proposed by
37*6236dae4SAndroid Build Coastguard Worker    * https://freedesktop.org/wiki/CommonExtendedAttributes/
38*6236dae4SAndroid Build Coastguard Worker    */
39*6236dae4SAndroid Build Coastguard Worker   { "user.xdg.referrer.url", CURLINFO_REFERER },
40*6236dae4SAndroid Build Coastguard Worker   { "user.mime_type",        CURLINFO_CONTENT_TYPE },
41*6236dae4SAndroid Build Coastguard Worker   { NULL,                    CURLINFO_NONE } /* last element, abort here */
42*6236dae4SAndroid Build Coastguard Worker };
43*6236dae4SAndroid Build Coastguard Worker 
44*6236dae4SAndroid Build Coastguard Worker /* returns a new URL that needs to be freed */
45*6236dae4SAndroid Build Coastguard Worker /* @unittest: 1621 */
46*6236dae4SAndroid Build Coastguard Worker #ifdef UNITTESTS
47*6236dae4SAndroid Build Coastguard Worker char *stripcredentials(const char *url);
48*6236dae4SAndroid Build Coastguard Worker #else
49*6236dae4SAndroid Build Coastguard Worker static
50*6236dae4SAndroid Build Coastguard Worker #endif
stripcredentials(const char * url)51*6236dae4SAndroid Build Coastguard Worker char *stripcredentials(const char *url)
52*6236dae4SAndroid Build Coastguard Worker {
53*6236dae4SAndroid Build Coastguard Worker   CURLU *u;
54*6236dae4SAndroid Build Coastguard Worker   CURLUcode uc;
55*6236dae4SAndroid Build Coastguard Worker   char *nurl;
56*6236dae4SAndroid Build Coastguard Worker   u = curl_url();
57*6236dae4SAndroid Build Coastguard Worker   if(u) {
58*6236dae4SAndroid Build Coastguard Worker     uc = curl_url_set(u, CURLUPART_URL, url, CURLU_GUESS_SCHEME);
59*6236dae4SAndroid Build Coastguard Worker     if(uc)
60*6236dae4SAndroid Build Coastguard Worker       goto error;
61*6236dae4SAndroid Build Coastguard Worker 
62*6236dae4SAndroid Build Coastguard Worker     uc = curl_url_set(u, CURLUPART_USER, NULL, 0);
63*6236dae4SAndroid Build Coastguard Worker     if(uc)
64*6236dae4SAndroid Build Coastguard Worker       goto error;
65*6236dae4SAndroid Build Coastguard Worker 
66*6236dae4SAndroid Build Coastguard Worker     uc = curl_url_set(u, CURLUPART_PASSWORD, NULL, 0);
67*6236dae4SAndroid Build Coastguard Worker     if(uc)
68*6236dae4SAndroid Build Coastguard Worker       goto error;
69*6236dae4SAndroid Build Coastguard Worker 
70*6236dae4SAndroid Build Coastguard Worker     uc = curl_url_get(u, CURLUPART_URL, &nurl, 0);
71*6236dae4SAndroid Build Coastguard Worker     if(uc)
72*6236dae4SAndroid Build Coastguard Worker       goto error;
73*6236dae4SAndroid Build Coastguard Worker 
74*6236dae4SAndroid Build Coastguard Worker     curl_url_cleanup(u);
75*6236dae4SAndroid Build Coastguard Worker 
76*6236dae4SAndroid Build Coastguard Worker     return nurl;
77*6236dae4SAndroid Build Coastguard Worker   }
78*6236dae4SAndroid Build Coastguard Worker error:
79*6236dae4SAndroid Build Coastguard Worker   curl_url_cleanup(u);
80*6236dae4SAndroid Build Coastguard Worker   return NULL;
81*6236dae4SAndroid Build Coastguard Worker }
82*6236dae4SAndroid Build Coastguard Worker 
xattr(int fd,const char * attr,const char * value)83*6236dae4SAndroid Build Coastguard Worker static int xattr(int fd,
84*6236dae4SAndroid Build Coastguard Worker                  const char *attr, /* name of the xattr */
85*6236dae4SAndroid Build Coastguard Worker                  const char *value)
86*6236dae4SAndroid Build Coastguard Worker {
87*6236dae4SAndroid Build Coastguard Worker   int err = 0;
88*6236dae4SAndroid Build Coastguard Worker   if(value) {
89*6236dae4SAndroid Build Coastguard Worker #ifdef DEBUGBUILD
90*6236dae4SAndroid Build Coastguard Worker     if(getenv("CURL_FAKE_XATTR")) {
91*6236dae4SAndroid Build Coastguard Worker       printf("%s => %s\n", attr, value);
92*6236dae4SAndroid Build Coastguard Worker       return 0;
93*6236dae4SAndroid Build Coastguard Worker     }
94*6236dae4SAndroid Build Coastguard Worker #endif
95*6236dae4SAndroid Build Coastguard Worker #ifdef HAVE_FSETXATTR_6
96*6236dae4SAndroid Build Coastguard Worker     err = fsetxattr(fd, attr, value, strlen(value), 0, 0);
97*6236dae4SAndroid Build Coastguard Worker #elif defined(HAVE_FSETXATTR_5)
98*6236dae4SAndroid Build Coastguard Worker     err = fsetxattr(fd, attr, value, strlen(value), 0);
99*6236dae4SAndroid Build Coastguard Worker #elif defined(__FreeBSD_version) || defined(__MidnightBSD_version)
100*6236dae4SAndroid Build Coastguard Worker     {
101*6236dae4SAndroid Build Coastguard Worker       ssize_t rc = extattr_set_fd(fd, EXTATTR_NAMESPACE_USER,
102*6236dae4SAndroid Build Coastguard Worker                                   attr, value, strlen(value));
103*6236dae4SAndroid Build Coastguard Worker       /* FreeBSD's extattr_set_fd returns the length of the extended
104*6236dae4SAndroid Build Coastguard Worker          attribute */
105*6236dae4SAndroid Build Coastguard Worker       err = (rc < 0 ? -1 : 0);
106*6236dae4SAndroid Build Coastguard Worker     }
107*6236dae4SAndroid Build Coastguard Worker #endif
108*6236dae4SAndroid Build Coastguard Worker   }
109*6236dae4SAndroid Build Coastguard Worker   return err;
110*6236dae4SAndroid Build Coastguard Worker }
111*6236dae4SAndroid Build Coastguard Worker /* store metadata from the curl request alongside the downloaded
112*6236dae4SAndroid Build Coastguard Worker  * file using extended attributes
113*6236dae4SAndroid Build Coastguard Worker  */
fwrite_xattr(CURL * curl,const char * url,int fd)114*6236dae4SAndroid Build Coastguard Worker int fwrite_xattr(CURL *curl, const char *url, int fd)
115*6236dae4SAndroid Build Coastguard Worker {
116*6236dae4SAndroid Build Coastguard Worker   int i = 0;
117*6236dae4SAndroid Build Coastguard Worker   int err = xattr(fd, "user.creator", "curl");
118*6236dae4SAndroid Build Coastguard Worker 
119*6236dae4SAndroid Build Coastguard Worker   /* loop through all xattr-curlinfo pairs and abort on a set error */
120*6236dae4SAndroid Build Coastguard Worker   while(!err && mappings[i].attr) {
121*6236dae4SAndroid Build Coastguard Worker     char *value = NULL;
122*6236dae4SAndroid Build Coastguard Worker     CURLcode result = curl_easy_getinfo(curl, mappings[i].info, &value);
123*6236dae4SAndroid Build Coastguard Worker     if(!result && value)
124*6236dae4SAndroid Build Coastguard Worker       err = xattr(fd, mappings[i].attr, value);
125*6236dae4SAndroid Build Coastguard Worker     i++;
126*6236dae4SAndroid Build Coastguard Worker   }
127*6236dae4SAndroid Build Coastguard Worker   if(!err) {
128*6236dae4SAndroid Build Coastguard Worker     char *nurl = stripcredentials(url);
129*6236dae4SAndroid Build Coastguard Worker     if(!nurl)
130*6236dae4SAndroid Build Coastguard Worker       return 1;
131*6236dae4SAndroid Build Coastguard Worker     err = xattr(fd, "user.xdg.origin.url", nurl);
132*6236dae4SAndroid Build Coastguard Worker     curl_free(nurl);
133*6236dae4SAndroid Build Coastguard Worker   }
134*6236dae4SAndroid Build Coastguard Worker   return err;
135*6236dae4SAndroid Build Coastguard Worker }
136*6236dae4SAndroid Build Coastguard Worker #endif
137