Example #1
0
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;
}
Example #3
0
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;
}
Example #4
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;
}