diff --git a/hfs/catalog.c b/hfs/catalog.c index a6e7db8..512d441 100644 --- a/hfs/catalog.c +++ b/hfs/catalog.c @@ -1050,6 +1050,116 @@ int chmodFile(const char* pathName, int mode, Volume* volume) { return TRUE; } +int attrFile(const char* pathName, const char* flags, Volume* volume) { + HFSPlusCatalogRecord* record; + uint16_t flag = 0; + uint16_t mask = 0; + uint16_t file_mask = kIsOnDesk|kColor|kIsShared|kHasNoINITs|kHasBeenInited|kHasCustomIcon|kIsStationery|kNameLocked|kHasBundle|kIsInvisible|kIsAlias; + uint16_t folder_mask = kIsOnDesk|kColor|kHasCustomIcon|kNameLocked|kIsInvisible; + + while (*flags != 0) { + switch(*flags++) { + // custom icon + case 'C': + flag |= kHasCustomIcon; + case 'c': + mask |= kHasCustomIcon; + break; + + // invisible + case 'V': + flag |= kIsInvisible; + case 'v': + mask |= kIsInvisible; + break; + + // inited + case 'I': + flag |= kHasBeenInited; + case 'i': + mask |= kHasBeenInited; + break; + + // no INIT resource + case 'N': + flag |= kHasNoINITs; + case 'n': + mask |= kHasNoINITs; + break; + + // located on the desktop + case 'D': + flag |= kIsOnDesk; + case 'd': + mask |= kIsOnDesk; + break; + + // name locked + case 'S': + flag |= kNameLocked; + case 's': + mask |= kNameLocked; + break; + + // stationery pad file + case 'T': + flag |= kIsStationery; + case 't': + mask |= kIsStationery; + break; + + // shared + case 'M': + flag |= kIsShared; + case 'm': + mask |= kIsShared; + break; + + // alias file + case 'A': + flag |= kIsAlias; + case 'a': + mask |= kIsAlias; + break; + + // has bundle + case 'B': + flag |= kHasBundle; + case 'b': + mask |= kHasBundle; + break; + } + } + + record = getRecordFromPath(pathName, volume, NULL, NULL); + + if(record == NULL) { + printf("Path '%s' not found.\n", pathName); + return FALSE; + } + + if(record->recordType == kHFSPlusFolderRecord) { + flag &= folder_mask; + mask &= folder_mask; + ((HFSPlusCatalogFolder*)record)->userInfo.finderFlags = (((HFSPlusCatalogFolder*)record)->userInfo.finderFlags & (~mask)) | flag; + printf("%x\n", ((HFSPlusCatalogFolder*)record)->userInfo.finderFlags); + } else if(record->recordType == kHFSPlusFileRecord) { + flag &= file_mask; + mask &= file_mask; + ((HFSPlusCatalogFile*)record)->userInfo.finderFlags = (((HFSPlusCatalogFile*)record)->userInfo.finderFlags & (~mask)) | flag; + printf("%x\n", ((HFSPlusCatalogFile*)record)->userInfo.finderFlags); + } else { + printf("unknown record type %x\n", record->recordType); + return FALSE; + } + + updateCatalog(volume, record); + + free(record); + + return TRUE; +} + int chownFile(const char* pathName, uint32_t owner, uint32_t group, Volume* volume) { HFSPlusCatalogRecord* record; diff --git a/hfs/hfs.c b/hfs/hfs.c index 88b71d8..de553e1 100644 --- a/hfs/hfs.c +++ b/hfs/hfs.c @@ -131,6 +131,16 @@ void cmd_chmod(Volume* volume, int argc, const char *argv[]) { } } +void cmd_attr(Volume* volume, int argc, const char *argv[]) { + int mode; + + if(argc > 2) { + attrFile(argv[1], argv[2], volume); + } else { + printf("Not enough arguments"); + } +} + void cmd_extractall(Volume* volume, int argc, const char *argv[]) { HFSPlusCatalogRecord* record; char cwd[1024]; @@ -237,7 +247,7 @@ int main(int argc, const char *argv[]) { TestByteOrder(); if(argc < 3) { - printf("usage: %s \n", argv[0]); + printf("usage: %s \n", argv[0]); return 0; } @@ -271,6 +281,8 @@ int main(int argc, const char *argv[]) { cmd_rm(volume, argc - 2, argv + 2); } else if(strcmp(argv[2], "chmod") == 0) { cmd_chmod(volume, argc - 2, argv + 2); + } else if(strcmp(argv[2], "attr") == 0) { + cmd_attr(volume, argc - 2, argv + 2); } else if(strcmp(argv[2], "extract") == 0) { cmd_extract(volume, argc - 2, argv + 2); } else if(strcmp(argv[2], "extractall") == 0) {