Created
November 14, 2022 11:33
Copy/Set the 'Date Added' of files and folders in macOS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Simple tool to copy the 'Date Added' on macOS. | |
//based on code witten by Andrew Neitsch <andrew@neitsch.ca> and an hint of Ken Thomases | |
//<https://stackoverflow.com/q/39685113/> | |
//compile using "cc -o cpda cpda.c" | |
//tested on macOS 10.13 and 12 on APFS | |
//test with "mdls -name kMDItemDateAdded ..." <https://stackoverflow.com/a/71264110/394431> | |
//use with "cp -a ..." and "find -exec ..." | |
#include <stdlib.h> | |
#include <string.h> | |
#include <sys/attr.h> | |
#include <unistd.h> | |
/* | |
* Get kMDItemDateAdded of path. | |
* | |
* Returns: | |
* • 0 on success | |
* • 1 if a system call failed: check errno | |
* • 2 if something else went wrong | |
*/ | |
int get_date_added(const char* path, struct timespec * out) { | |
attrgroup_t request_attrs = ATTR_CMN_RETURNED_ATTRS | ATTR_CMN_ADDEDTIME; | |
struct attrlist request; | |
memset(&request, 0, sizeof(request)); | |
request.bitmapcount = ATTR_BIT_MAP_COUNT; | |
request.commonattr = request_attrs; | |
typedef struct { | |
u_int32_t length; | |
attribute_set_t returned; | |
struct timespec added; | |
} __attribute__((aligned(4), packed)) response_buf_t; | |
response_buf_t response; | |
int err = getattrlist(path, &request, &response, sizeof(response), 0); | |
if (err != 0) { | |
return 1; | |
} | |
if (response.length != sizeof(response)) { | |
// Need a different-sized buffer; but provided one of exactly required | |
// size?! | |
return 2; | |
} | |
if (response.returned.commonattr != request_attrs) { | |
// Didn’t get back all requested common attributes | |
return 2; | |
} | |
out->tv_sec = response.added.tv_sec; | |
out->tv_nsec = response.added.tv_nsec; | |
return 0; | |
} | |
/* | |
* Set kMDItemDateAdded of path. | |
* | |
* Returns: | |
* • 0 on success | |
* • 1 if a system call failed: check errno | |
*/ | |
int set_date_added(const char* path, struct timespec in) { | |
attrgroup_t request_attrs = ATTR_CMN_ADDEDTIME; | |
struct attrlist request; | |
memset(&request, 0, sizeof(request)); | |
request.bitmapcount = ATTR_BIT_MAP_COUNT; | |
request.commonattr = request_attrs; | |
typedef struct { | |
struct timespec added; | |
} __attribute__((aligned(4), packed)) request_buf_t; | |
request_buf_t request_buf; | |
request_buf.added.tv_sec = in.tv_sec; | |
request_buf.added.tv_nsec = in.tv_nsec; | |
int err = setattrlist(path, &request, &request_buf, sizeof(request_buf), 0); | |
if (err != 0) { | |
return 1; | |
} | |
return 0; | |
} | |
#include <stdio.h> | |
/* | |
* | |
* Make it possible to call the code above from a simple cmd line tool | |
* to copy the 'Date Added' from one file to another. | |
* | |
*/ | |
int main(int argc, char *argv[]) { | |
if (argc != 3) { | |
printf("Usage:\n%s source_path target_path\n\nCopy the kMDItemDateAdded from source_path to target_path.\n", argv[0]); | |
return 64; | |
} | |
struct timespec t; | |
int err; | |
err = get_date_added(argv[1], &t); | |
if (err != 0) { | |
return err; | |
} | |
err = set_date_added(argv[2], t); | |
if (err != 0) { | |
return err; | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Can you help me transfer "set_date_added" func to swift code?
All I have at the moment is:
But it allways falls
Here in comments or by the URL:
https://stackoverflow.com/questions/78366352/change-kmditemdateadded-date-added-files-metadata-attribute-via-swift-cod