static int ar_entry_ctime(lua_State *L) { struct archive_entry* self = *ar_entry_check(L, 1); int is_set; int num_results; if ( NULL == self ) return 0; is_set = ( lua_gettop(L) >= 2 ); num_results = 0; if ( archive_entry_ctime_is_set(self) ) { num_results = 2; lua_pushnumber(L, archive_entry_ctime(self)); lua_pushnumber(L, archive_entry_ctime_nsec(self)); } if ( is_set ) { if ( lua_isnil(L, 2) ) { archive_entry_unset_ctime(self); } else if ( lua_istable(L, 2) ) { lua_rawgeti(L, 2, 1); lua_rawgeti(L, 2, 2); archive_entry_set_ctime(self, lua_tonumber(L, -2), lua_tonumber(L, -1)); } else { archive_entry_set_ctime(self, lua_tonumber(L, 2), lua_tonumber(L, 3)); } } return num_results; }
int packing_append_file_attr(struct packing *pack, const char *filepath, const char *newpath, const char *uname, const char *gname, mode_t perm, u_long fflags) { int fd; int retcode = EPKG_OK; int ret; time_t source_time; struct stat st; struct archive_entry *entry, *sparse_entry; bool unset_timestamp; const char *source_date_epoch; char buf[32768]; int len; entry = archive_entry_new(); archive_entry_copy_sourcepath(entry, filepath); pkg_debug(2, "Packing file '%s'", filepath); if (lstat(filepath, &st) != 0) { pkg_emit_errno("lstat", filepath); retcode = EPKG_FATAL; goto cleanup; } ret = archive_read_disk_entry_from_file(pack->aread, entry, -1, &st); if (ret != ARCHIVE_OK) { pkg_emit_error("%s: %s", filepath, archive_error_string(pack->aread)); retcode = EPKG_FATAL; goto cleanup; } if (newpath != NULL) archive_entry_set_pathname(entry, newpath); if (archive_entry_filetype(entry) != AE_IFREG) { archive_entry_set_size(entry, 0); } if (uname != NULL && uname[0] != '\0') { archive_entry_set_uname(entry, uname); } if (gname != NULL && gname[0] != '\0') { archive_entry_set_gname(entry, gname); } if (fflags > 0) archive_entry_set_fflags(entry, fflags, 0); if (perm != 0) archive_entry_set_perm(entry, perm); unset_timestamp = pkg_object_bool(pkg_config_get("UNSET_TIMESTAMP")); if (unset_timestamp) { archive_entry_unset_atime(entry); archive_entry_unset_ctime(entry); archive_entry_unset_mtime(entry); archive_entry_unset_birthtime(entry); } if ((source_date_epoch = getenv("SOURCE_DATE_EPOCH")) != NULL) { if (source_date_epoch[strspn(source_date_epoch, "0123456789")] != '\0') { pkg_emit_error("Bad environment variable " "SOURCE_DATE_EPOCH: %s", source_date_epoch); retcode = EPKG_FATAL; goto cleanup; } source_time = strtoll(source_date_epoch, NULL, 10); archive_entry_set_atime(entry, source_time, 0); archive_entry_set_ctime(entry, source_time, 0); archive_entry_set_mtime(entry, source_time, 0); archive_entry_set_birthtime(entry, source_time, 0); } archive_entry_linkify(pack->resolver, &entry, &sparse_entry); if (sparse_entry != NULL && entry == NULL) entry = sparse_entry; archive_write_header(pack->awrite, entry); if (archive_entry_size(entry) <= 0) goto cleanup; if ((fd = open(filepath, O_RDONLY)) < 0) { pkg_emit_errno("open", filepath); retcode = EPKG_FATAL; goto cleanup; } while ((len = read(fd, buf, sizeof(buf))) > 0) { if (archive_write_data(pack->awrite, buf, len) == -1) { pkg_emit_errno("archive_write_data", "archive write error"); retcode = EPKG_FATAL; break; } } if (len == -1) { pkg_emit_errno("read", "file read error"); retcode = EPKG_FATAL; } close(fd); cleanup: archive_entry_free(entry); return (retcode); }
int packing_append_file_attr(struct packing *pack, const char *filepath, const char *newpath, const char *uname, const char *gname, mode_t perm) { int fd; char *map; int retcode = EPKG_OK; int ret; struct stat st; struct archive_entry *entry, *sparse_entry; bool unset_timestamp; entry = archive_entry_new(); archive_entry_copy_sourcepath(entry, filepath); pkg_debug(2, "Packing file '%s'", filepath); if (lstat(filepath, &st) != 0) { pkg_emit_errno("lstat", filepath); retcode = EPKG_FATAL; goto cleanup; } ret = archive_read_disk_entry_from_file(pack->aread, entry, -1, &st); if (ret != ARCHIVE_OK) { pkg_emit_error("%s: %s", filepath, archive_error_string(pack->aread)); retcode = EPKG_FATAL; goto cleanup; } if (newpath != NULL) archive_entry_set_pathname(entry, newpath); if (archive_entry_filetype(entry) != AE_IFREG) { archive_entry_set_size(entry, 0); } if (uname != NULL && uname[0] != '\0') { if (pack->pass) { struct passwd* pw = getpwnam(uname); if (pw == NULL) { pkg_emit_error("Unknown user: '******'", uname); retcode = EPKG_FATAL; goto cleanup; } archive_entry_set_uid(entry, pw->pw_uid); } archive_entry_set_uname(entry, uname); } if (gname != NULL && gname[0] != '\0') { if (pack->pass) { struct group *gr = (getgrnam(gname)); if (gr == NULL) { pkg_emit_error("Unknown group: '%s'", gname); retcode = EPKG_FATAL; goto cleanup; } archive_entry_set_gid(entry, gr->gr_gid); } archive_entry_set_gname(entry, gname); } if (perm != 0) archive_entry_set_perm(entry, perm); pkg_config_bool(PKG_CONFIG_UNSET_TIMESTAMP, &unset_timestamp); if (unset_timestamp) { archive_entry_unset_atime(entry); archive_entry_unset_ctime(entry); archive_entry_unset_mtime(entry); archive_entry_unset_birthtime(entry); } archive_entry_linkify(pack->resolver, &entry, &sparse_entry); if (sparse_entry != NULL && entry == NULL) entry = sparse_entry; archive_write_header(pack->awrite, entry); if (archive_entry_size(entry) > 0) { if ((fd = open(filepath, O_RDONLY)) < 0) { pkg_emit_errno("open", filepath); retcode = EPKG_FATAL; goto cleanup; } if (st.st_size > SSIZE_MAX) { char buf[BUFSIZ]; int len; while ((len = read(fd, buf, sizeof(buf))) > 0) if (archive_write_data(pack->awrite, buf, len) == -1) { pkg_emit_errno("archive_write_data", "archive write error"); retcode = EPKG_FATAL; break; } if (len == -1) { pkg_emit_errno("read", "file read error"); retcode = EPKG_FATAL; } close(fd); } else { if ((map = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0)) != MAP_FAILED) { close(fd); if (archive_write_data(pack->awrite, map, st.st_size) == -1) { pkg_emit_errno("archive_write_data", "archive write error"); retcode = EPKG_FATAL; } munmap(map, st.st_size); } else { close(fd); pkg_emit_errno("open", filepath); retcode = EPKG_FATAL; goto cleanup; } } } cleanup: archive_entry_free(entry); return (retcode); }