ZIP_EXTERN zip_int64_t zip_dir_add(struct zip *za, const char *name, zip_flags_t flags) { size_t len; zip_int64_t idx; char *s; struct zip_source *source; if (ZIP_IS_RDONLY(za)) { _zip_error_set(&za->error, ZIP_ER_RDONLY, 0); return -1; } if (name == NULL) { _zip_error_set(&za->error, ZIP_ER_INVAL, 0); return -1; } s = NULL; len = strlen(name); if (name[len-1] != '/') { if ((s=(char *)malloc(len+2)) == NULL) { _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); return -1; } strcpy(s, name); s[len] = '/'; s[len+1] = '\0'; } if ((source=zip_source_buffer(za, NULL, 0, 0)) == NULL) { free(s); return -1; } idx = _zip_file_replace(za, ZIP_UINT64_MAX, s ? s : name, source, flags); free(s); if (idx < 0) zip_source_free(source); else { if (zip_file_set_external_attributes(za, (zip_uint64_t)idx, 0, ZIP_OPSYS_DEFAULT, ZIP_EXT_ATTRIB_DEFAULT_DIR) < 0) { zip_delete(za, (zip_uint64_t)idx); return -1; } } return idx; }
/** * Save OS type and permissions into external attributes * @return libzip error code (ZIP_ER_MEMORY or ZIP_ER_RDONLY) */ int FileNode::updateExternalAttributes() const { assert(id >= 0); assert (zip != NULL); // save UNIX attributes in high word mode_t mode = m_mode << 16; // save DOS attributes in low byte // http://msdn.microsoft.com/en-us/library/windows/desktop/gg258117%28v=vs.85%29.aspx // http://en.wikipedia.org/wiki/File_Allocation_Table#attributes if (is_dir) { // FILE_ATTRIBUTE_DIRECTORY mode |= 0x10; } if (name[0] == '.') { // FILE_ATTRIBUTE_HIDDEN mode |= 2; } if (!(mode & S_IWUSR)) { // FILE_ATTRIBUTE_READONLY mode |= 1; } return zip_file_set_external_attributes (zip, id, 0, ZIP_OPSYS_UNIX, mode); }