static int prp_readdir(const char* path, void* buf, fuse_fill_dir_t filler, off_t offset, fuse_file_info* fi) { if (strcmp(path, "/") == 0) { // PRP Root: filler(buf, ".", NULL, 0); filler(buf, "..", NULL, 0); filler(buf, PAGEINFO, NULL, 0); // PRP Types: for (CLASSLIST::iterator it = CLASSES.begin(); it != CLASSES.end(); it++) filler(buf, it->clsName, NULL, 0); return 0; } else { // Type directory plString typeStr = plString(path + 1); if (typeStr.empty()) return -ENOENT; short type = plFactory::ClassIndex(typeStr); if (type < 0) return -ENOENT; // Make sure the type is actually present bool hasType = false; for (CLASSLIST::iterator it = CLASSES.begin(); it != CLASSES.end() && !hasType; it++) { if (it->clsIdx == type) hasType = true; } if (!hasType) return -ENOENT; filler(buf, ".", NULL, 0); filler(buf, "..", NULL, 0); std::vector<plKey> keys = RESMGR.getKeys(PAGE->getLocation(), type); for (std::vector<plKey>::iterator it = keys.begin(); it != keys.end(); it++) { filler(buf, CleanFileName((*it)->getName() + ".po"), NULL, 0); filler(buf, CleanFileName((*it)->getName() + ".prc"), NULL, 0); } return 0; } }
JBoolean JFSBindingList::GetBinding ( const JCharacter* origFileName, const JFSBinding** binding ) { // ignore # and ~ on end JString fileName = origFileName; CleanFileName(&fileName); // read content JString content; ifstream input(origFileName); content.Read(input, kContentLength); input.close(); // scan bindings for match -- check content types first const JSize count = GetElementCount(); for (JIndex j=0; j<=1; j++) { const JBoolean isContent = JNegate(j); for (JIndex i=1; i<=count; i++) { *binding = GetBinding(i); if ((**binding).IsContentBinding() == isContent && (**binding).Match(fileName, content)) { return kJTrue; } } } if (itsUseDefaultFlag && itsUserDefault != NULL) { *binding = itsUserDefault; return kJTrue; } if (itsUseDefaultFlag && itsSystemDefault != NULL) { *binding = itsSystemDefault; return kJTrue; } *binding = NULL; return kJFalse; }
static int prp_getattr(const char* path, struct stat* stbuf) { memset(stbuf, 0, sizeof(struct stat)); if (strcmp(path, "/") == 0) { stbuf->st_mode = S_IFDIR | 0555; stbuf->st_nlink = 2 + CLASSES.size(); stbuf->st_uid = s_uid; stbuf->st_gid = s_gid; stbuf->st_atime = s_fatime; stbuf->st_mtime = s_fmtime; stbuf->st_ctime = s_fctime; } else if (strcmp(path, "/" PAGEINFO) == 0) { stbuf->st_mode = S_IFREG | 0444; stbuf->st_nlink = 1; stbuf->st_uid = s_uid; stbuf->st_gid = s_gid; stbuf->st_size = 0; stbuf->st_atime = s_fatime; stbuf->st_mtime = s_fmtime; stbuf->st_ctime = s_fctime; } else { // Find the type first plString typeStr = plString(path + 1).beforeFirst('/'); if (typeStr.empty()) return -ENOENT; short type = plFactory::ClassIndex(typeStr); if (type < 0) return -ENOENT; // Make sure the type is actually present bool hasType = false; for (CLASSLIST::iterator it = CLASSES.begin(); it != CLASSES.end() && !hasType; it++) { if (it->clsIdx == type) hasType = true; } if (!hasType) return -ENOENT; plString fname = plString(path + 1).afterFirst('/'); if (fname.empty()) { // Directory stbuf->st_mode = S_IFDIR | 0555; stbuf->st_nlink = 2 + RESMGR.getKeys(PAGE->getLocation(), type).size(); stbuf->st_uid = s_uid; stbuf->st_gid = s_gid; stbuf->st_atime = s_fatime; stbuf->st_mtime = s_fmtime; stbuf->st_ctime = s_fctime; } else { // File plString ftype = fname.afterLast('.'); fname = fname.beforeLast('.'); std::vector<plKey> keys = RESMGR.getKeys(PAGE->getLocation(), type); for (std::vector<plKey>::iterator it = keys.begin(); it != keys.end(); it++) { if (CleanFileName((*it)->getName()) == fname) { stbuf->st_mode = S_IFREG | 0444; stbuf->st_nlink = 1; stbuf->st_uid = s_uid; stbuf->st_gid = s_gid; stbuf->st_size = (ftype == "po") ? (*it)->getObjSize() : 0; stbuf->st_atime = s_fatime; stbuf->st_mtime = s_fmtime; stbuf->st_ctime = s_fctime; return 0; } } return -ENOENT; } } return 0; }
int main(int argc, char* argv[]) { if (argc < 2 || argc > 3) { doHelp(); return 0; } eDirection direction = kRepack; ST::string filename = argv[1]; ST_ssize_t dotLoc = filename.find_last('.'); if (argc == 3) { if (strcmp(argv[1], "-c") == 0) direction = kCreate; else if (strcmp(argv[1], "-x") == 0) direction = kExtract; else if (strcmp(argv[1], "-r") == 0) direction = kRepack; else { doHelp(); return 1; } filename = argv[2]; } else if (dotLoc >= 0 && filename.substr(dotLoc) == ".prd") { direction = kCreate; } plResManager rm; hsFileStream S, OS; if (!S.open(filename, fmRead)) { ST::printf(stderr, "Error opening {} for reading!", filename); return 1; } plPageInfo* page = new plPageInfo(); //int len; short maj = 63, min = 11; unsigned int i, j; if (direction == kExtract || direction == kRepack) { S.close(); delete page; page = rm.ReadPage(filename, true); OS.open(filenameConvert(filename, kExtract), fmCreate); OS.write(4, "PRD"); OS.writeShort(page->getAge().size()); OS.writeStr(page->getAge()); OS.writeShort(page->getPage().size()); OS.writeStr(page->getPage()); if (rm.getVer().isUniversal()) { maj = 0x7FFF; min = 0x7FFF; } else if (rm.getVer().isEoa()) { maj = -1; min = 1; } else if (rm.getVer().isHexIsle()) { maj = -1; min = 2; } else { maj = rm.getVer().revMajor(); min = rm.getVer().revMinor(); } OS.writeShort(maj); OS.writeShort(min); plLocation loc = page->getLocation(); loc.write(&OS); OS.close(); std::vector<short> types = rm.getTypes(loc); #ifdef _WIN32 CreateDirectoryW(getOutputDir(filename, page).to_wchar().data(), NULL); #else mkdir(getOutputDir(filename, page).c_str(), S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH); #endif for (i=0; i<types.size(); i++) { std::vector<plKey> objs = rm.getKeys(loc, types[i]); for (j=0; j<objs.size(); j++) { ST::string po_file = ST::format("{}[{04X}]{}.po", getOutputDir(filename, page), types[i], CleanFileName(objs[j]->getName())); OS.open(po_file, fmCreate); OS.setVer(rm.getVer()); rm.WriteCreatable(&OS, objs[j]->getObj()); OS.close(); } } } if (direction == kRepack) { filename = filenameConvert(filename, kExtract); S.open(filename, fmRead); } if (direction == kCreate || direction == kRepack) { OS.open(filenameConvert(filename, kCreate), fmCreate); char sig[4]; S.read(4, sig); if (strncmp(sig, "PRD", sizeof(sig)) != 0) { fputs("Error: Invalid input file!\n", stderr); OS.close(); S.close(); return 1; } ST::string ageName = S.readStr(S.readShort()); ST::string pageName = S.readStr(S.readShort()); page->setAge(ageName); page->setPage(pageName); maj = S.readShort(); min = S.readShort(); if (maj == 0x7FFF) { OS.setVer(PlasmaVer::pvUniversal); } else if (maj == -1) { if (min == 1) OS.setVer(PlasmaVer::pvEoa); else if (min == 2) OS.setVer(PlasmaVer::pvHex); } else if (maj == 70) { OS.setVer(PlasmaVer::pvMoul); } else if (maj == 63) { if (min == 11) OS.setVer(PlasmaVer::pvPrime); if (min == 12) OS.setVer(PlasmaVer::pvPots); } else { ST::printf(stderr, "Error: Invalid Plasma version: {}.{}\n", maj, min); OS.close(); S.close(); return 1; } S.setVer(OS.getVer()); plLocation loc; loc.read(&S); page->setLocation(loc); page->setReleaseVersion(0); page->setFlags(plPageInfo::kBasicChecksum); S.close(); std::vector<ST::string> inFiles; std::vector<short> inClasses; hsFileStream PS; PS.setVer(OS.getVer()); #ifdef _WIN32 ST::string pattern = ST::format("{}*.po", getOutputDir(filename, page)); WIN32_FIND_DATAW fd; HANDLE fr = FindFirstFileW(pattern.to_wchar().data(), &fd); if (fr != NULL) { do { ST::string po_file = getOutputDir(filename, page) + fd.cFileName; inFiles.push_back(po_file); PS.open(po_file, fmRead); short classType = PS.readShort(); PS.close(); bool haveClass = false; for (j=0; j<inClasses.size(); j++) if (inClasses[j] == classType) { haveClass = true; } if (!haveClass) inClasses.push_back(classType); } while (FindNextFileW(fr, &fd)); FindClose(fr); } #else dirent** des; unsigned int nEntries = scandir(getOutputDir(filename, page).c_str(), &des, &selPO, &alphasort); for (i=0; i<nEntries; i++) { ST::string po_file = getOutputDir(filename, page) + des[i]->d_name; inFiles.push_back(po_file); PS.open(po_file, fmRead); short classType = PS.readShort(); PS.close(); bool haveClass = false; for (j=0; j<inClasses.size(); j++) if (inClasses[j] == classType) { haveClass = true; } if (!haveClass) inClasses.push_back(classType); } #endif page->setClassList(inClasses); page->write(&OS); page->setDataStart(OS.pos()); plKeyCollector keys; for (i=0; i<inFiles.size(); i++) { plKey key = new plKeyData(); PS.open(inFiles[i], fmRead); PS.setVer(S.getVer()); unsigned int poLen = PS.size(); uint8_t* objBuf = new uint8_t[poLen]; key->setFileOff(OS.pos()); key->setObjSize(poLen); PS.read(poLen, objBuf); OS.write(poLen, objBuf); delete[] objBuf; PS.seek(2); key->readUoid(&PS); PS.close(); keys.add(key); } page->setIndexStart(OS.pos()); keys.sortKeys(page->getLocation()); std::vector<short> types = keys.getTypes(page->getLocation()); //if (types != inClasses) // throw "Wtf, mate?"; OS.writeInt(types.size()); for (i=0; i<types.size(); i++) { std::vector<plKey> kList = keys.getKeys(page->getLocation(), types[i]); OS.writeShort(pdUnifiedTypeMap::MappedToPlasma(types[i], OS.getVer())); unsigned int lenPos = OS.pos(); if (!OS.getVer().isUruSP() && !OS.getVer().isUniversal()) { OS.writeInt(0); OS.writeByte(0); } OS.writeInt(kList.size()); for (j=0; j<kList.size(); j++) kList[j]->write(&OS); if (!OS.getVer().isUruSP() && !OS.getVer().isUniversal()) { unsigned int nextPos = OS.pos(); OS.seek(lenPos); OS.writeInt(nextPos - lenPos - 4); OS.seek(nextPos); } } if (OS.getVer().isNewPlasma()) page->setChecksum(OS.pos()); else page->setChecksum(OS.pos() - page->getDataStart()); page->writeSums(&OS); OS.close(); } // Delete temp files with the repack option if (direction == kRepack) { #ifdef _WIN32 ST::string pattern = ST::format("{}*.po", getOutputDir(filename, page)); WIN32_FIND_DATAW rfd; HANDLE rfr = FindFirstFileW(pattern.to_wchar().data(), &rfd); if (rfr != NULL) { do { ST::string po_file = getOutputDir(filename, page) + rfd.cFileName; DeleteFileW(po_file.to_wchar().data()); } while (FindNextFileW(rfr, &rfd)); FindClose(rfr); } RemoveDirectoryW(getOutputDir(filename, page).to_wchar().data()); DeleteFileW(filename.to_wchar().data()); #else dirent** rdes; unsigned int nEntries = scandir(getOutputDir(filename, page).c_str(), &rdes, &selAll, &alphasort); for (i=0; i<nEntries; i++) { ST::string po_file = getOutputDir(filename, page) + rdes[i]->d_name; unlink(po_file.c_str()); } rmdir(getOutputDir(filename, page).c_str()); unlink(filename.c_str()); #endif } return 0; }