PageRenderTime 46ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/src/tool_xattr.c

http://github.com/bagder/curl
C | 139 lines | 91 code | 15 blank | 33 comment | 15 complexity | b262e25e60463ae63668bc516aeabb91 MD5 | raw file
  1. /***************************************************************************
  2. * _ _ ____ _
  3. * Project ___| | | | _ \| |
  4. * / __| | | | |_) | |
  5. * | (__| |_| | _ <| |___
  6. * \___|\___/|_| \_\_____|
  7. *
  8. * Copyright (C) 1998 - 2019, 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.haxx.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. ***************************************************************************/
  22. #include "tool_setup.h"
  23. #ifdef HAVE_FSETXATTR
  24. # include <sys/xattr.h> /* header from libc, not from libattr */
  25. # define USE_XATTR
  26. #elif defined(__FreeBSD_version) && (__FreeBSD_version > 500000)
  27. # include <sys/types.h>
  28. # include <sys/extattr.h>
  29. # define USE_XATTR
  30. #endif
  31. #include "tool_xattr.h"
  32. #include "memdebug.h" /* keep this as LAST include */
  33. #ifdef USE_XATTR
  34. /* mapping table of curl metadata to extended attribute names */
  35. static const struct xattr_mapping {
  36. const char *attr; /* name of the xattr */
  37. CURLINFO info;
  38. } mappings[] = {
  39. /* mappings proposed by
  40. * https://freedesktop.org/wiki/CommonExtendedAttributes/
  41. */
  42. { "user.xdg.origin.url", CURLINFO_EFFECTIVE_URL },
  43. { "user.mime_type", CURLINFO_CONTENT_TYPE },
  44. { NULL, CURLINFO_NONE } /* last element, abort loop here */
  45. };
  46. /* returns TRUE if a new URL is returned, that then needs to be freed */
  47. /* @unittest: 1621 */
  48. #ifdef UNITTESTS
  49. bool stripcredentials(char **url);
  50. #else
  51. static
  52. #endif
  53. bool stripcredentials(char **url)
  54. {
  55. CURLU *u;
  56. CURLUcode uc;
  57. char *nurl;
  58. u = curl_url();
  59. if(u) {
  60. uc = curl_url_set(u, CURLUPART_URL, *url, 0);
  61. if(uc)
  62. goto error;
  63. uc = curl_url_set(u, CURLUPART_USER, NULL, 0);
  64. if(uc)
  65. goto error;
  66. uc = curl_url_set(u, CURLUPART_PASSWORD, NULL, 0);
  67. if(uc)
  68. goto error;
  69. uc = curl_url_get(u, CURLUPART_URL, &nurl, 0);
  70. if(uc)
  71. goto error;
  72. curl_url_cleanup(u);
  73. *url = nurl;
  74. return TRUE;
  75. }
  76. error:
  77. curl_url_cleanup(u);
  78. return FALSE;
  79. }
  80. /* store metadata from the curl request alongside the downloaded
  81. * file using extended attributes
  82. */
  83. int fwrite_xattr(CURL *curl, int fd)
  84. {
  85. int i = 0;
  86. int err = 0;
  87. /* loop through all xattr-curlinfo pairs and abort on a set error */
  88. while(err == 0 && mappings[i].attr != NULL) {
  89. char *value = NULL;
  90. CURLcode result = curl_easy_getinfo(curl, mappings[i].info, &value);
  91. if(!result && value) {
  92. bool freeptr = FALSE;
  93. if(CURLINFO_EFFECTIVE_URL == mappings[i].info)
  94. freeptr = stripcredentials(&value);
  95. if(value) {
  96. #ifdef HAVE_FSETXATTR_6
  97. err = fsetxattr(fd, mappings[i].attr, value, strlen(value), 0, 0);
  98. #elif defined(HAVE_FSETXATTR_5)
  99. err = fsetxattr(fd, mappings[i].attr, value, strlen(value), 0);
  100. #elif defined(__FreeBSD_version)
  101. {
  102. ssize_t rc = extattr_set_fd(fd, EXTATTR_NAMESPACE_USER,
  103. mappings[i].attr, value, strlen(value));
  104. /* FreeBSD's extattr_set_fd returns the length of the extended
  105. attribute */
  106. err = (rc < 0 ? -1 : 0);
  107. }
  108. #endif
  109. if(freeptr)
  110. curl_free(value);
  111. }
  112. }
  113. i++;
  114. }
  115. return err;
  116. }
  117. #else
  118. int fwrite_xattr(CURL *curl, int fd)
  119. {
  120. (void)curl;
  121. (void)fd;
  122. return 0;
  123. }
  124. #endif