tool_xattr.c 3.7 KB

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