Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/hrbrmstr/xattrs
π Work With Filesystem Object Extended Attributes β https://hrbrmstr.github.io/xattrs/index.html
https://github.com/hrbrmstr/xattrs
r r-cyber rstats xattr xattr-support
Last synced: 23 days ago
JSON representation
π Work With Filesystem Object Extended Attributes β https://hrbrmstr.github.io/xattrs/index.html
- Host: GitHub
- URL: https://github.com/hrbrmstr/xattrs
- Owner: hrbrmstr
- License: other
- Created: 2018-05-30T12:02:27.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2019-08-23T14:45:19.000Z (about 5 years ago)
- Last Synced: 2024-08-03T22:18:20.531Z (3 months ago)
- Topics: r, r-cyber, rstats, xattr, xattr-support
- Language: C++
- Homepage: https://rud.is/b/2018/05/30/os-secrets-exposed-extracting-extended-file-attributes-and-exploring-hidden-download-urls-with-the-xattrs-package/
- Size: 104 KB
- Stars: 20
- Watchers: 4
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: README.Rmd
- License: LICENSE
Awesome Lists containing this project
- jimsghstars - hrbrmstr/xattrs - π Work With Filesystem Object Extended Attributes β https://hrbrmstr.github.io/xattrs/index.html (C++)
README
---
output:
rmarkdown::github_document:
df_print: kable
---
```{r pkg-knitr-opts, include=FALSE}
hrbrpkghelpr::global_opts()
``````{r badges, results='asis', echo=FALSE, cache=FALSE}
hrbrpkghelpr::stinking_badges()
``````{r description, results='asis', echo=FALSE, cache=FALSE}
hrbrpkghelpr::yank_title_and_description()
```## NOTE
I don't think this will work on Windows.
## What's Inside The Tin
The following functions are implemented:
```{r ingredients, results='asis', echo=FALSE, cache=FALSE}
hrbrpkghelpr::describe_ingredients()
```## Installation
```{r install-ex, results='asis', echo=FALSE, cache=FALSE}
hrbrpkghelpr::install_block()
```## Usage
```{r usage, cache=FALSE}
library(xattrs)
library(tidyverse) # for printing# current verison
packageVersion("xattrs")```
### Basic Operation
Extended attributes seem to get stripped when R builds pkgs so until I can figure out an easy way not to do that, just find any file on your system that has an `@` next to the permissions string in an `ls -l` directory listing.
```{r 1, eval=FALSE}
sample_file <- "~/Downloads/AdvancedTechniquesWithAWSGlueETLJobs.pdf"list_xattrs(sample_file)
## [1] "com.apple.metadata:kMDItemWhereFroms"
## [2] "com.apple.quarantine"get_xattr_size(sample_file, "com.apple.metadata:kMDItemWhereFroms")
## 157
```Extended attributes can be _anything_ so it makes alot of sense to work with the contents as a raw vector:
```{r 2, eval=FALSE}
get_xattr_raw(sample_file, "com.apple.metadata:kMDItemWhereFroms")
## [1] 62 70 6c 69 73 74 30 30 a2 01 02 5f 10 6b 68 74 74 70 73 3a 2f
## [22] 2f 66 69 6c 65 73 2e 73 6c 61 63 6b 2e 63 6f 6d 2f 66 69 6c 65
## [43] 73 2d 70 72 69 2f 54 33 56 31 5a 44 51 48 4d 2d 46 44 4a 47 59
## [64] 4b 57 4a 33 2f 64 6f 77 6e 6c 6f 61 64 2f 61 64 76 61 6e 63 65
## [85] 64 74 65 63 68 6e 69 71 75 65 73 77 69 74 68 61 77 73 67 6c 75
## [106] 65 65 74 6c 6a 6f 62 73 5f 5f 31 5f 2e 70 64 66 50 08 0b 79 00
## [127] 00 00 00 00 00 01 01 00 00 00 00 00 00 00 03 00 00 00 00 00 00
## [148] 00 00 00 00 00 00 00 00 00 7a
```There is a "string" version of the function, but it may return "nothing" if there are embedded NULLs or other breaking characters in the contents:
```{r 3, eval=FALSE}
get_xattr(sample_file, "com.apple.metadata:kMDItemWhereFroms")
## [1] "bplist00\xa2\001\002_\020khttps://files.slack.com/files-pri/T3V1ZDQHM-FDJGYKWJ3/download/advancedtechniqueswithawsglueetljobs__1_.pdfP\b\vy"
```You are really better off doing this if you really want a raw string conversion:
```{r 4, eval=FALSE}
readBin(get_xattr_raw(sample_file, "com.apple.metadata:kMDItemWhereFroms"), "character")
## [1] "bplist00\xa2\001\002_\020khttps://files.slack.com/files-pri/T3V1ZDQHM-FDJGYKWJ3/download/advancedtechniqueswithawsglueetljobs__1_.pdfP\b\vy"
```More often than not (on macOS) extended attributes are "binary property lists" (or "binary plist" for short). You can test to see if the returned raw vector is likely a binary plist:
```{r 5, eval=FALSE}
is_bplist(get_xattr_raw(sample_file, "com.apple.metadata:kMDItemWhereFroms"))
## [1] TRUE
```If it is, you can get the data out of it. For now, this makes a system call to `plutil` on macOS and `plistutil` on other systems. You'll be given a hint on how to install `plistutil` if it's not found.
```{r 6, eval=FALSE}
read_bplist(get_xattr_raw(sample_file, "com.apple.metadata:kMDItemWhereFroms"))
## $plist
## $plist$array
## $plist$array$string
## $plist$array$string[[1]]
## [1] "https://files.slack.com/files-pri/T3V1ZDQHM-FDJGYKWJ3/download/advancedtechniqueswithawsglueetljobs__1_.pdf"
##
##
## $plist$array$string
## list()
##
##
## attr(,"version")
## [1] "1.0"
```This is R, so you should really consider doing this instead of any of the above #rectanglesrule:
```{r 7, eval=FALSE}
get_xattr_df(sample_file)
## # A tibble: 2 x 3
## name size contents
##
## 1 com.apple.metadata:kMDItemWhereFroms 157
## 2 com.apple.quarantine 56
```you can live dangerously even with data frames, tho:
```{r 8, eval=FALSE}
get_xattr_df(sample_file) %>%
mutate(txt = map_chr(contents, readBin, "character")) # potentially "dangerous"
## # A tibble: 2 x 4
## name size contents txt
##
## 1 com.apple.metadata⦠157
## 1 com.apple.quarantine 55
## 2 com.apple.metadata:kMDItemWhereFroms 46
## 3 com.apple.lastuseddate#PS 13
## 4 com.apple.metadata:_kMDItemUserTags 3
## 5 com.apple.metadata:kMDItemDownloadedDate 2
## 6 com.apple.diskimages.fsck 1
## 7 com.apple.diskimages.recentcksum 1
## 8 com.apple.FinderInfo 1
## 9 com.apple.metadata:com_apple_mail_dateReceived 1
## 10 com.apple.metadata:com_apple_mail_dateSent 1
## 11 com.apple.metadata:com_apple_mail_isRemoteAttachment 1
```And we can work with `com.apple.metadata:kMDItemWhereFroms` binary plist data in bulk:
```{r 10, eval=FALSE}
filter(xdf, name == "com.apple.metadata:kMDItemWhereFroms") %>%
filter(map_lgl(contents, is_bplist)) %>%
mutate(converted = map(contents, read_bplist)) %>%
select(size, converted) %>%
mutate(converted = map(converted, ~flatten_chr(.x$plist$array$string))) %>%
unnest() %>%
mutate(converted = urltools::domain(converted)) # you don't rly need to see the full URLs for this example
## # A tibble: 44 x 2
## size converted
##
## 1 189 dl.packetstormsecurity.net
## 2 129 files.slack.com
## 3 120 files.slack.com
## 4 117 files.slack.com
## 5 592 irma.nps.gov
## 6 157 files.slack.com
## 7 624 github-production-release-asset-2e65be.s3.amazonaws.com
## 8 197 images.unsplash.com
## 9 197 images.unsplash.com
## 10 185 files.slack.com
## # β¦ with 34 more rows
```### Full Suite
```{r full-suite}
# Create a temp file for the example
tf <- tempfile(fileext = ".csv")
write.csv(mtcars, tf)# has attributes? (shld be FALSE)
has_xattrs(tf)
get_xattr(tf, "is.rud.setting")# set an attribute
set_xattr(tf, "is.rud.setting.a", "first attribut")
get_xattr(tf, "is.rud.setting.a")
get_xattr_size(tf, "is.rud.setting.a")# shld be TRUE
has_xattrs(tf)set_xattr(tf, "is.rud.setting.b", "second attribute")
get_xattr(tf, "is.rud.setting.b")
get_xattr_size(tf, "is.rud.setting.b")# overwrite an attribute
set_xattr(tf, "is.rud.setting.a", "first attribute")
get_xattr(tf, "is.rud.setting.a")
get_xattr_size(tf, "is.rud.setting.a")# see all the attributes
list_xattrs(tf)# data frame vs individual functions
get_xattr_df(tf)# remove attribute
rm_xattr(tf, "is.rud.setting")
get_xattr(tf, "is.rud.setting")# cleanup
unlink(tf)
```## xattrs Metrics
```{r cloc, echo=FALSE}
cloc::cloc_pkg_md()
```## Code of Conduct
Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms.