/*-*-c++-*- * $Id$ * * This file is part of plptools. * * Copyright (C) 1999-2001 Fritz Elfert * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include "rpcs32.h" #include "bufferstore.h" #include "bufferarray.h" #include "ppsocket.h" using namespace std; rpcs32::rpcs32(ppsocket * _skt) { skt = _skt; mtCacheS5mx = 0; reset(); } Enum rpcs32:: getCmdLine(const char *process, string &ret) { bufferStore a; Enum res; a.addStringT(process); if (!sendCommand(rpcs::GET_CMDLINE, a)) return rfsv::E_PSI_FILE_DISC; if ((res = getResponse(a, true)) == rfsv::E_PSI_GEN_NONE) ret = a.getString(0); return res; } Enum rpcs32:: getMachineInfo(machineInfo &mi) { bufferStore a; Enum res; if (!sendCommand(rpcs::GET_MACHINE_INFO, a)) return rfsv::E_PSI_FILE_DISC; if ((res = getResponse(a, true)) != rfsv::E_PSI_GEN_NONE) return res; if (a.getLen() != 256) return rfsv::E_PSI_GEN_FAIL; mi.machineType = (enum rpcs::machs)a.getDWord(0); strncpy(mi.machineName, a.getString(16), 16); mi.machineName[16] = '\0'; mi.machineUID = a.getDWord(44); mi.machineUID <<= 32; mi.machineUID |= a.getDWord(40); mi.countryCode = a.getDWord(56); mi.uiLanguage = (enum rpcs::languages)a.getDWord(164); mi.romMajor = a.getByte(4); mi.romMinor = a.getByte(5); mi.romBuild = a.getWord(6); mi.romSize = a.getDWord(140); mi.ramSize = a.getDWord(136); mi.ramMaxFree = a.getDWord(144); mi.ramFree = a.getDWord(148); mi.ramDiskSize = a.getDWord(152); mi.registrySize = a.getDWord(156); mi.romProgrammable = (a.getDWord(160) != 0); mi.displayWidth = a.getDWord(32); mi.displayHeight = a.getDWord(36); mi.time.tv_low = a.getDWord(48); mi.time.tv_high = a.getDWord(52); mi.tz.utc_offset = a.getDWord(60); mi.tz.dst_zones = a.getDWord(64); mi.tz.home_zone = a.getDWord(68); PsiZone::getInstance().setZone(mi.tz); mi.mainBatteryInsertionTime.tv_low = a.getDWord(72); mi.mainBatteryInsertionTime.tv_high = a.getDWord(76); mi.mainBatteryStatus = (enum rpcs::batterystates)a.getDWord(80); mi.mainBatteryUsedTime.tv_low = a.getDWord(84); mi.mainBatteryUsedTime.tv_high = a.getDWord(88); mi.mainBatteryCurrent = a.getDWord(92); mi.mainBatteryUsedPower = a.getDWord(96); mi.mainBatteryVoltage = a.getDWord(100); mi.mainBatteryMaxVoltage = a.getDWord(104); mi.backupBatteryStatus = (enum rpcs::batterystates)a.getDWord(108); mi.backupBatteryVoltage = a.getDWord(112); mi.backupBatteryMaxVoltage = a.getDWord(116); mi.externalPowerUsedTime.tv_low = a.getDWord(124); mi.externalPowerUsedTime.tv_high = a.getDWord(128); mi.externalPower = (a.getDWord(120) != 0); mtCacheS5mx |= 8; if (res == rfsv::E_PSI_GEN_NONE) { if (!strcmp(mi.machineName, "SERIES5mx")) mtCacheS5mx |= 2; } return res; } static unsigned long hhh; Enum rpcs32:: regOpenIter(u_int32_t uid, char *match, u_int16_t &handle) { bufferStore a; Enum res; cout << "Oiter" << endl; a.addDWord(uid); a.addDWord(strlen(match)); a.addStringT(match); if (!sendCommand(rpcs::REG_OPEN_ITER, a)) return rfsv::E_PSI_FILE_DISC; res = getResponse(a, true); cout << "ro: r=" << res << " a=" << a << endl; if (a.getLen() == 2) handle = a.getWord(0); return rfsv::E_PSI_GEN_NONE; } Enum rpcs32:: regReadIter(u_int16_t handle) { bufferStore a; Enum res; cout << "Riter" << endl; a.addWord(handle); if (!sendCommand(rpcs::REG_READ_ITER, a)) return rfsv::E_PSI_FILE_DISC; res = getResponse(a, true); cout << "ro: r=" << res << " a=" << a << endl; if ((a.getLen() == 3) && (a.getByte(2) == 0xff)) return rfsv::E_PSI_FILE_EOF; return rfsv::E_PSI_GEN_NONE; } Enum rpcs32:: configOpen(u_int16_t &handle, u_int32_t size) { bufferStore a; Enum res; a.addDWord(size); if (!sendCommand(rpcs::CONFIG_OPEN, a)) return rfsv::E_PSI_FILE_DISC; res = getResponse(a, true); if (res == rfsv::E_PSI_GEN_NONE && (a.getLen() >= 2)) handle = a.getWord(0); return res; } Enum rpcs32:: configRead(u_int32_t size, bufferStore &ret) { bufferStore a; u_int16_t handle; Enum res; ret.init(); if ((res = configOpen(handle, size)) != rfsv::E_PSI_GEN_NONE) return res; do { a.i
#include "BigIntegerAlgorithms.hh"

BigUnsigned gcd(BigUnsigned a, BigUnsigned b) {
	BigUnsigned trash;
	// Neat in-place alternating technique.
	for (;;) {
		if (b.isZero())
			return a;
		a.divideWithRemainder(b, trash);
		if (a.isZero())
			return b;
		b.divideWithRemainder(a, trash);
	}
}

void extendedEuclidean(BigInteger m, BigInteger n,
		BigInteger &g, BigInteger &r, BigInteger &s) {
	if (&g == &r || &g == &s || &r == &s)
		throw "BigInteger extendedEuclidean: Outputs are aliased";
	BigInteger r1(1), s1(0), r2(0), s2(1), q;
	/* Invariants:
	 * r1*m(orig) + s1*n(orig) == m(current)
	 * r2*m(orig) + s2*n(orig) == n(current) */
	for (;;) {
		if (n.isZero()) {
			r = r1; s = s1; g = m;
			return;
		}
		// Subtract q times the second invariant from the first invariant.
		m.divideWithRemainder(n, q);
		r1 -= q*r2; s1 -= q*s2;

		if (m.isZero()) {
			r = r2; s = s2; g = n;
			return;
		}
		// Subtract q times the first invariant from the second invariant.
		n.divideWithRemainder(m, q);
		r2 -= q*r1; s2 -= q*s1;
	}
}

BigUnsigned modinv(const BigInteger &x, const BigUnsigned &n) {
	BigInteger g, r, s;
	extendedEuclidean(x, n, g, r, s);
	if (g == 1)
		// r*x + s*n == 1, so r*x === 1 (mod n), so r is the answer.
		return (r % n).getMagnitude(); // (r % n) will be nonnegative
	else
		throw "BigInteger modinv: x and n have a common factor";
}

BigUnsigned modexp(const BigInteger &base, const BigUnsigned &exponent,
		const BigUnsigned &modulus) {
	BigUnsigned ans = 1, base2 = (base % modulus).getMagnitude();
	BigUnsigned::Index i = exponent.bitLength();
	// For each bit of the exponent, most to least significant...
	while (i > 0) {
		i--;
		// Square.
		ans *= ans;
		ans %= modulus;
		// And multiply if the bit is a 1.
		if (exponent.getBit(i)) {
			ans *= base2;
			ans %= modulus;
		}
	}
	return ans;
}