VYPR
High severity8.8NVD Advisory· Published Jun 10, 2026

CVE-2026-52754

CVE-2026-52754

Description

GhidraServer's PKI authentication allows impersonation via null signature, enabling privilege escalation and data exfiltration.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

GhidraServer's PKI authentication allows impersonation via null signature, enabling privilege escalation and data exfiltration.

Vulnerability

GhidraServer, in PKI mode, contains an authentication bypass vulnerability in the PKIAuthenticationModule.authenticate() method. This flaw allows any user with a valid CA-signed certificate to impersonate other users by presenting their public certificate with a null signature. The vulnerability has been present since Ghidra's initial open-source release in March 2019 and affects all versions through at least 12.0.4 [3]. The affected code path is reachable when GhidraServer is configured to use PKI authentication and a client attempts to authenticate with a null signature [3].

Exploitation

An attacker needs a valid CA-signed certificate and network access to the GhidraServer. The attacker can present their public certificate along with a null signature during the authentication process. The server, instead of verifying the signature, will skip the verification step when the signature is null and proceed to authenticate the user based on the certificate's Distinguished Name (DN) [3]. This allows the attacker to bypass the intended signature verification and impersonate any user whose certificate is trusted by the server [4].

Impact

Successful exploitation allows an attacker to impersonate other users on the GhidraServer, potentially leading to privilege escalation. Attackers can gain unauthorized access to shared reverse engineering databases for exfiltration, modify repository access controls, and permanently compromise server integrity [4]. The scope of the compromise is limited to the users and resources accessible by the impersonated user on the GhidraServer.

Mitigation

Ghidra version 12.1 and later contain a fix for this vulnerability [1]. The vulnerability has been present since Ghidra's initial open-source release in March 2019 and affects all versions through at least 12.0.4 [3]. No specific workarounds are mentioned in the available references, and the vulnerability is not listed as being actively exploited in the wild or part of the CISA KEV catalog.

AI Insight generated on Jun 10, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected products

1

Patches

3
78729379e471

GP-6155 Refactor of PKI framework support

41 files changed · +1169 1285
  • Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/string/translate/libretranslate/LibreTranslateStringTranslationService.java+1 2 modified
    @@ -401,8 +401,7 @@ private <T> T asyncRequest(HttpRequest request, BodyHandler<T> bodyHandler, Task
     			// if possible, unwrap the exception that happened inside the future
     			Throwable cause = e.getCause();
     			Msg.error(this, "Error during HTTP request [%s]".formatted(request.uri()), cause);
    -			throw (cause instanceof IOException)
    -					? (IOException) cause
    +			throw (cause instanceof IOException) ? (IOException) cause
     					: new IOException("Error during HTTP request", cause);
     		}
     		finally {
    
  • Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/AbstractProgramLoader.java+1 1 modified
    @@ -19,6 +19,7 @@
     import java.io.InputStream;
     import java.util.*;
     
    +import generic.hash.HashUtilities;
     import ghidra.app.plugin.processors.generic.MemoryBlockDefinition;
     import ghidra.app.util.Option;
     import ghidra.app.util.OptionUtils;
    @@ -36,7 +37,6 @@
     import ghidra.program.model.symbol.*;
     import ghidra.program.util.DefaultLanguageService;
     import ghidra.program.util.GhidraProgramUtilities;
    -import ghidra.util.HashUtilities;
     import ghidra.util.MD5Utilities;
     import ghidra.util.exception.*;
     import ghidra.util.task.TaskMonitor;
    
  • Ghidra/Features/Base/src/main/java/ghidra/formats/gfilesystem/FileCache.java+1 0 modified
    @@ -23,6 +23,7 @@
     
     import org.apache.commons.collections4.map.ReferenceMap;
     
    +import generic.hash.HashUtilities;
     import ghidra.app.util.bin.*;
     import ghidra.util.*;
     import ghidra.util.exception.CancelledException;
    
  • Ghidra/Features/Base/src/main/java/ghidra/formats/gfilesystem/FSUtilities.java+1 0 modified
    @@ -31,6 +31,7 @@
     import org.apache.commons.io.FilenameUtils;
     
     import docking.widgets.OptionDialog;
    +import generic.hash.HashUtilities;
     import ghidra.app.util.bin.ByteProvider;
     import ghidra.formats.gfilesystem.annotations.FileSystemInfo;
     import ghidra.formats.gfilesystem.fileinfo.FileType;
    
  • Ghidra/Features/Base/src/main/java/ghidra/framework/HeadlessGhidraApplicationConfiguration.java+4 4 modified
    @@ -4,9 +4,9 @@
      * Licensed under the Apache License, Version 2.0 (the "License");
      * you may not use this file except in compliance with the License.
      * You may obtain a copy of the License at
    - * 
    + *
      *      http://www.apache.org/licenses/LICENSE-2.0
    - * 
    + *
      * Unless required by applicable law or agreed to in writing, software
      * distributed under the License is distributed on an "AS IS" BASIS,
      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    @@ -21,7 +21,7 @@
     import generic.jar.ResourceFile;
     import ghidra.GhidraClassLoader;
     import ghidra.framework.preferences.Preferences;
    -import ghidra.net.ApplicationTrustManagerFactory;
    +import ghidra.net.DefaultTrustManagerFactory;
     import ghidra.util.Msg;
     import ghidra.util.classfinder.ClassSearcher;
     import ghidra.util.exception.CancelledException;
    @@ -88,7 +88,7 @@ private void locateCACertsFile() {
     		for (ResourceFile appRoot : Application.getApplicationRootDirectories()) {
     			File cacertsFile = new File(appRoot.getAbsolutePath(), "cacerts");
     			if (cacertsFile.isFile()) {
    -				System.setProperty(ApplicationTrustManagerFactory.GHIDRA_CACERTS_PATH_PROPERTY,
    +				System.setProperty(DefaultTrustManagerFactory.GHIDRA_CACERTS_PATH_PROPERTY,
     					cacertsFile.getAbsolutePath());
     				break;
     			}
    
  • Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/BSimControlLaunchable.java+5 6 modified
    @@ -38,7 +38,7 @@
     import ghidra.features.bsim.query.ingest.BSimLaunchable;
     import ghidra.framework.*;
     import ghidra.framework.client.ClientUtil;
    -import ghidra.net.ApplicationKeyManagerUtils;
    +import ghidra.net.PKIUtils;
     import ghidra.util.Msg;
     import ghidra.util.exception.AssertException;
     import ghidra.util.exception.CancelledException;
    @@ -390,7 +390,7 @@ private static boolean verifyPEMFormat(File testFile) throws IOException {
     				if (line == null) {
     					break;
     				}
    -				if (line.startsWith(ApplicationKeyManagerUtils.BEGIN_CERT)) {
    +				if (line.startsWith(PKIUtils.BEGIN_CERT)) {
     					return true;
     				}
     			}
    @@ -557,11 +557,10 @@ private void generateSelfSignedCertificate(File certFile, File passFile)
     		PasswordProtection pp = new PasswordProtection(password);
     		try {
     			// TODO: should subjectAlternativeNames be supported?
    -			KeyStore keyStore = ApplicationKeyManagerUtils.createKeyStore(alias, "CN=BSimServer",
    -				365 * 2, null, null, "JKS", null, password);
    +			KeyStore keyStore = PKIUtils.createKeyStore(alias, "CN=BSimServer", 365 * 2, null,
    +				null, "JKS", null, password);
     
    -			ApplicationKeyManagerUtils.exportX509Certificates(keyStore.getCertificateChain(alias),
    -				certFile);
    +			PKIUtils.exportX509Certificates(keyStore.getCertificateChain(alias), certFile);
     			Key key = keyStore.getKey(alias, password);
     
     			try (FileOutputStream fout = new FileOutputStream(passFile);
    
  • Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/ingest/BSimLaunchable.java+2 2 modified
    @@ -34,7 +34,7 @@
     import ghidra.framework.client.ClientUtil;
     import ghidra.framework.client.HeadlessClientAuthenticator;
     import ghidra.framework.protocol.ghidra.GhidraURL;
    -import ghidra.net.SSLContextInitializer;
    +import ghidra.net.DefaultSSLContextInitializer;
     import ghidra.util.Msg;
     import ghidra.util.SystemUtilities;
     import ghidra.util.exception.CancelledException;
    @@ -1111,7 +1111,7 @@ public static void initializeApplication(ApplicationLayout layout, int type,
     
     		Application.initializeApplication(layout, config);
     
    -		SSLContextInitializer.initialize();
    +		DefaultSSLContextInitializer.initialize();
     		ghidra.framework.protocol.ghidra.Handler.registerHandler();
     		ghidra.features.bsim.query.postgresql.Handler.registerHandler();
     
    
  • Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/ingest/HeadlessBSimApplicationConfiguration.java+4 4 modified
    @@ -4,9 +4,9 @@
      * Licensed under the Apache License, Version 2.0 (the "License");
      * you may not use this file except in compliance with the License.
      * You may obtain a copy of the License at
    - * 
    + *
      *      http://www.apache.org/licenses/LICENSE-2.0
    - * 
    + *
      * Unless required by applicable law or agreed to in writing, software
      * distributed under the License is distributed on an "AS IS" BASIS,
      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    @@ -20,7 +20,7 @@
     
     import generic.jar.ResourceFile;
     import ghidra.framework.*;
    -import ghidra.net.ApplicationTrustManagerFactory;
    +import ghidra.net.DefaultTrustManagerFactory;
     import ghidra.util.classfinder.ClassSearcher;
     
     public class HeadlessBSimApplicationConfiguration extends ApplicationConfiguration {
    @@ -46,7 +46,7 @@ private void locateCACertsFile() {
     		for (ResourceFile appRoot : Application.getApplicationRootDirectories()) {
     			File cacertsFile = new File(appRoot.getAbsolutePath(), "cacerts");
     			if (cacertsFile.isFile()) {
    -				System.setProperty(ApplicationTrustManagerFactory.GHIDRA_CACERTS_PATH_PROPERTY,
    +				System.setProperty(DefaultTrustManagerFactory.GHIDRA_CACERTS_PATH_PROPERTY,
     					cacertsFile.getAbsolutePath());
     				break;
     			}
    
  • Ghidra/Features/BSim/src/test/java/ghidra/features/bsim/query/facade/TestNearestVectorResult.java+3 3 modified
    @@ -4,9 +4,9 @@
      * Licensed under the Apache License, Version 2.0 (the "License");
      * you may not use this file except in compliance with the License.
      * You may obtain a copy of the License at
    - * 
    + *
      *      http://www.apache.org/licenses/LICENSE-2.0
    - * 
    + *
      * Unless required by applicable law or agreed to in writing, software
      * distributed under the License is distributed on an "AS IS" BASIS,
      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    @@ -19,10 +19,10 @@
     import java.util.Date;
     import java.util.List;
     
    +import generic.hash.HashUtilities;
     import generic.lsh.vector.*;
     import ghidra.features.bsim.query.description.*;
     import ghidra.features.bsim.query.protocol.SimilarityVectorResult;
    -import ghidra.util.HashUtilities;
     import ghidra.xml.XmlPullParser;
     
     public class TestNearestVectorResult extends SimilarityVectorResult {
    
  • Ghidra/Features/BSim/src/test/java/ghidra/features/bsim/query/facade/TestSimilarityResult.java+3 3 modified
    @@ -4,9 +4,9 @@
      * Licensed under the Apache License, Version 2.0 (the "License");
      * you may not use this file except in compliance with the License.
      * You may obtain a copy of the License at
    - * 
    + *
      *      http://www.apache.org/licenses/LICENSE-2.0
    - * 
    + *
      * Unless required by applicable law or agreed to in writing, software
      * distributed under the License is distributed on an "AS IS" BASIS,
      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    @@ -19,10 +19,10 @@
     import java.io.InputStream;
     import java.util.Date;
     
    +import generic.hash.HashUtilities;
     import ghidra.features.bsim.query.description.ExecutableRecord;
     import ghidra.features.bsim.query.description.FunctionDescription;
     import ghidra.features.bsim.query.protocol.SimilarityResult;
    -import ghidra.util.HashUtilities;
     
     public class TestSimilarityResult extends SimilarityResult {
     //	protected static Random random = new Random();
    
  • Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/cart/CartFileSystem.java+1 1 modified
    @@ -23,14 +23,14 @@
     
     import com.google.gson.*;
     
    +import generic.hash.HashUtilities;
     import ghidra.app.util.bin.ByteProvider;
     import ghidra.app.util.bin.ByteProviderWrapper;
     import ghidra.formats.gfilesystem.*;
     import ghidra.formats.gfilesystem.annotations.FileSystemInfo;
     import ghidra.formats.gfilesystem.crypto.CryptoSession;
     import ghidra.formats.gfilesystem.fileinfo.*;
     import ghidra.framework.generic.auth.Password;
    -import ghidra.util.HashUtilities;
     import ghidra.util.exception.CancelledException;
     import ghidra.util.task.TaskMonitor;
     
    
  • Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/cart/CartV1Constants.java+3 3 modified
    @@ -4,9 +4,9 @@
      * Licensed under the Apache License, Version 2.0 (the "License");
      * you may not use this file except in compliance with the License.
      * You may obtain a copy of the License at
    - * 
    + *
      *      http://www.apache.org/licenses/LICENSE-2.0
    - * 
    + *
      * Unless required by applicable law or agreed to in writing, software
      * distributed under the License is distributed on an "AS IS" BASIS,
      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    @@ -22,7 +22,7 @@
     import java.util.Set;
     import java.util.stream.Collectors;
     
    -import ghidra.util.HashUtilities;
    +import generic.hash.HashUtilities;
     
     /**
      * Helper class from providing all the constants required for parsing a CaRT
    
  • Ghidra/Features/FileFormats/src/test/java/ghidra/file/formats/cart/CartV1FileTest.java+3 3 modified
    @@ -4,9 +4,9 @@
      * Licensed under the Apache License, Version 2.0 (the "License");
      * you may not use this file except in compliance with the License.
      * You may obtain a copy of the License at
    - * 
    + *
      *      http://www.apache.org/licenses/LICENSE-2.0
    - * 
    + *
      * Unless required by applicable law or agreed to in writing, software
      * distributed under the License is distributed on an "AS IS" BASIS,
      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    @@ -22,9 +22,9 @@
     import org.junit.Before;
     import org.junit.Test;
     
    +import generic.hash.HashUtilities;
     import ghidra.app.util.bin.BinaryReader;
     import ghidra.app.util.bin.ByteArrayProvider;
    -import ghidra.util.HashUtilities;
     
     public class CartV1FileTest {
     	CartV1File cartFile;
    
  • Ghidra/Features/GhidraServer/src/main/java/ghidra/server/remote/GhidraServer.java+7 8 modified
    @@ -45,8 +45,8 @@
     import ghidra.framework.Application;
     import ghidra.framework.ApplicationConfiguration;
     import ghidra.framework.remote.*;
    -import ghidra.net.ApplicationKeyManagerFactory;
    -import ghidra.net.SSLContextInitializer;
    +import ghidra.net.DefaultKeyManagerFactory;
    +import ghidra.net.DefaultSSLContextInitializer;
     import ghidra.server.RepositoryManager;
     import ghidra.server.UserManager;
     import ghidra.server.security.*;
    @@ -731,7 +731,7 @@ else if (s.equals("-autoProvision")) {
     		Application.initializeLogging(serverLogFile, serverLogFile);
     
     		// In the absence of module initialization - we must invoke directly
    -		SSLContextInitializer.initialize();
    +		DefaultSSLContextInitializer.initialize();
     
     		log = LogManager.getLogger(GhidraServer.class); // init log *after* initializing log system
     
    @@ -752,13 +752,12 @@ else if (s.equals("-autoProvision")) {
     			// Ensure that remote access hostname is properly set for RMI registration
     			String hostname = initRemoteAccessHostname();
     
    -			if (ApplicationKeyManagerFactory.getPreferredKeyStore() == null) {
    +			if (DefaultKeyManagerFactory.getPreferredKeyStore() == null) {
     				// keystore has not been identified - use self-signed certificate
    -				ApplicationKeyManagerFactory
    -						.setDefaultIdentity(new X500Principal("CN=GhidraServer"));
    -				ApplicationKeyManagerFactory.addSubjectAlternativeName(hostname);
    +				DefaultKeyManagerFactory.setDefaultIdentity(new X500Principal("CN=GhidraServer"));
    +				DefaultKeyManagerFactory.addSubjectAlternativeName(hostname);
     			}
    -			if (!ApplicationKeyManagerFactory.initialize()) {
    +			if (!DefaultKeyManagerFactory.initialize()) {
     				log.fatal("Failed to initialize PKI/SSL keystore");
     				System.exit(0);
     				return;
    
  • Ghidra/Features/GhidraServer/src/main/java/ghidra/server/security/PKIAuthenticationModule.java+6 7 modified
    @@ -50,7 +50,7 @@ public class PKIAuthenticationModule implements AuthenticationModule {
     	public PKIAuthenticationModule(boolean anonymousAllowed)
     			throws IOException, CertificateException {
     		this.anonymousAllowed = anonymousAllowed;
    -		authorities = ApplicationKeyManagerUtils.getTrustedIssuers();
    +		authorities = DefaultTrustManagerFactory.getTrustedIssuers();
     		if (authorities == null || authorities.length == 0) {
     			throw new IOException("trusted PKI Certificate Authorities have not been configured");
     		}
    @@ -72,8 +72,8 @@ public Callback[] getAuthenticationCallbacks() {
     		try {
     			byte[] token = TokenGenerator.getNewToken(TOKEN_SIZE);
     			boolean usingSelfSignedCert =
    -				ApplicationKeyManagerFactory.usingGeneratedSelfSignedCertificate();
    -			SignedToken signedToken = ApplicationKeyManagerUtils
    +				DefaultKeyManagerFactory.usingGeneratedSelfSignedCertificate();
    +			SignedToken signedToken = DefaultKeyManagerFactory
     					.getSignedToken(usingSelfSignedCert ? null : authorities, token);
     			sigCb = new SignatureCallback(authorities, token, signedToken.signature);
     		}
    @@ -127,8 +127,8 @@ public String authenticate(UserManager userMgr, Subject subject, Callback[] call
     			}
     
     			boolean usingSelfSignedCert =
    -				ApplicationKeyManagerFactory.usingGeneratedSelfSignedCertificate();
    -			if (!ApplicationKeyManagerUtils.isMySignature(usingSelfSignedCert ? null : authorities,
    +				DefaultKeyManagerFactory.usingGeneratedSelfSignedCertificate();
    +			if (!DefaultKeyManagerFactory.isMySignature(usingSelfSignedCert ? null : authorities,
     				token, sigCb.getServerSignature())) {
     				throw new FailedLoginException("Invalid Signature callback");
     			}
    @@ -138,8 +138,7 @@ public String authenticate(UserManager userMgr, Subject subject, Callback[] call
     				throw new FailedLoginException("user certificate not provided");
     			}
     
    -			ApplicationKeyManagerUtils.validateClient(certChain,
    -				ApplicationKeyManagerUtils.RSA_TYPE);
    +			DefaultTrustManagerFactory.validateClient(certChain, PKIUtils.RSA_TYPE);
     
     			byte[] sigBytes = sigCb.getSignature();
     			if (sigBytes != null) {
    
  • Ghidra/Features/GhidraServer/src/main/java/ghidra/server/security/SSHAuthenticationModule.java+16 16 modified
    @@ -4,9 +4,9 @@
      * Licensed under the Apache License, Version 2.0 (the "License");
      * you may not use this file except in compliance with the License.
      * You may obtain a copy of the License at
    - * 
    + *
      *      http://www.apache.org/licenses/LICENSE-2.0
    - * 
    + *
      * Unless required by applicable law or agreed to in writing, software
      * distributed under the License is distributed on an "AS IS" BASIS,
      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    @@ -75,9 +75,9 @@ public Callback[] addAuthenticationCallbacks(Callback[] primaryAuthCallbacks) {
     		byte[] token = TokenGenerator.getNewToken(TOKEN_SIZE);
     		try {
     			boolean usingSelfSignedCert =
    -				ApplicationKeyManagerFactory.usingGeneratedSelfSignedCertificate();
    -			SignedToken signedToken = ApplicationKeyManagerUtils.getSignedToken(
    -				usingSelfSignedCert ? null : ApplicationKeyManagerUtils.getTrustedIssuers(), token);
    +				DefaultKeyManagerFactory.usingGeneratedSelfSignedCertificate();
    +			SignedToken signedToken = DefaultKeyManagerFactory.getSignedToken(
    +				usingSelfSignedCert ? null : DefaultTrustManagerFactory.getTrustedIssuers(), token);
     			list.add(new SSHSignatureCallback(token, signedToken.signature));
     		}
     		catch (Exception e) {
    @@ -88,9 +88,9 @@ public Callback[] addAuthenticationCallbacks(Callback[] primaryAuthCallbacks) {
     
     	public boolean hasSignedSSHCallback(Callback[] callbacks) {
     		if (callbacks != null) {
    -			for (int i = 0; i < callbacks.length; i++) {
    -				if (callbacks[i] instanceof SSHSignatureCallback) {
    -					SSHSignatureCallback sshCb = (SSHSignatureCallback) callbacks[i];
    +			for (Callback callback : callbacks) {
    +				if (callback instanceof SSHSignatureCallback) {
    +					SSHSignatureCallback sshCb = (SSHSignatureCallback) callback;
     					return sshCb.isSigned();
     				}
     			}
    @@ -154,12 +154,12 @@ public String authenticate(UserManager userMgr, Subject subject, Callback[] call
     		NameCallback nameCb = null;
     		SSHSignatureCallback sshCb = null;
     		if (callbacks != null) {
    -			for (int i = 0; i < callbacks.length; i++) {
    -				if (callbacks[i] instanceof NameCallback) {
    -					nameCb = (NameCallback) callbacks[i];
    +			for (Callback callback : callbacks) {
    +				if (callback instanceof NameCallback) {
    +					nameCb = (NameCallback) callback;
     				}
    -				if (callbacks[i] instanceof SSHSignatureCallback) {
    -					sshCb = (SSHSignatureCallback) callbacks[i];
    +				if (callback instanceof SSHSignatureCallback) {
    +					sshCb = (SSHSignatureCallback) callback;
     				}
     			}
     		}
    @@ -197,9 +197,9 @@ public String authenticate(UserManager userMgr, Subject subject, Callback[] call
     		boolean isValid = false;
     		try {
     			boolean usingSelfSignedCert =
    -				ApplicationKeyManagerFactory.usingGeneratedSelfSignedCertificate();
    -			isValid = ApplicationKeyManagerUtils.isMySignature(
    -				usingSelfSignedCert ? null : ApplicationKeyManagerUtils.getTrustedIssuers(), token,
    +				DefaultKeyManagerFactory.usingGeneratedSelfSignedCertificate();
    +			isValid = DefaultKeyManagerFactory.isMySignature(
    +				usingSelfSignedCert ? null : DefaultTrustManagerFactory.getTrustedIssuers(), token,
     				sshCb.getServerSignature());
     		}
     		catch (Exception e) {
    
  • Ghidra/Features/GhidraServer/src/main/java/ghidra/server/ServerAdmin.java+3 2 modified
    @@ -4,9 +4,9 @@
      * Licensed under the Apache License, Version 2.0 (the "License");
      * you may not use this file except in compliance with the License.
      * You may obtain a copy of the License at
    - * 
    + *
      *      http://www.apache.org/licenses/LICENSE-2.0
    - * 
    + *
      * Unless required by applicable law or agreed to in writing, software
      * distributed under the License is distributed on an "AS IS" BASIS,
      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    @@ -20,6 +20,7 @@
     
     import javax.security.auth.x500.X500Principal;
     
    +import generic.hash.HashUtilities;
     import generic.jar.ResourceFile;
     import ghidra.GhidraApplicationLayout;
     import ghidra.GhidraLaunchable;
    
  • Ghidra/Features/GhidraServer/src/main/java/ghidra/server/UserManager.java+3 2 modified
    @@ -4,9 +4,9 @@
      * Licensed under the Apache License, Version 2.0 (the "License");
      * you may not use this file except in compliance with the License.
      * You may obtain a copy of the License at
    - * 
    + *
      *      http://www.apache.org/licenses/LICENSE-2.0
    - * 
    + *
      * Unless required by applicable law or agreed to in writing, software
      * distributed under the License is distributed on an "AS IS" BASIS,
      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    @@ -25,6 +25,7 @@
     import org.apache.logging.log4j.LogManager;
     import org.apache.logging.log4j.Logger;
     
    +import generic.hash.HashUtilities;
     import ghidra.framework.remote.User;
     import ghidra.framework.store.local.LocalFileSystem;
     import ghidra.util.*;
    
  • Ghidra/Features/PDB/src/main/java/pdb/symbolserver/HttpSymbolServer.java+6 8 modified
    @@ -155,10 +155,10 @@ private HttpRequest.Builder request(String str) throws IOException {
     	@Override
     	public boolean exists(String filename, TaskMonitor monitor) {
     		try {
    -			HttpRequest request = request(filename)
    -					.timeout(Duration.ofMillis(HTTP_REQUEST_TIMEOUT_MS))
    -					.method("HEAD", BodyPublishers.noBody())
    -					.build();
    +			HttpRequest request =
    +				request(filename).timeout(Duration.ofMillis(HTTP_REQUEST_TIMEOUT_MS))
    +						.method("HEAD", BodyPublishers.noBody())
    +						.build();
     
     			Msg.debug(this,
     				logPrefix() + ": Checking exist for [" + filename + "]: " + request.toString());
    @@ -182,8 +182,7 @@ public SymbolServerInputStream getFileStream(String filename, TaskMonitor monito
     		monitor.setMessage("Connecting to " + serverURI);
     
     		HttpRequest request = request(filename).GET().build();
    -		Msg.debug(this,
    -			logPrefix() + ": Getting file [" + filename + "]: " + request.toString());
    +		Msg.debug(this, logPrefix() + ": Getting file [" + filename + "]: " + request.toString());
     		CompletableFuture<HttpResponse<InputStream>> futureResponse =
     			HttpClients.getHttpClient().sendAsync(request, BodyHandlers.ofInputStream());
     		CancelledListener l = () -> futureResponse.cancel(true);
    @@ -215,8 +214,7 @@ public SymbolServerInputStream getFileStream(String filename, TaskMonitor monito
     			// if possible, unwrap the exception that happened inside the future
     			Throwable cause = e.getCause();
     			Msg.error(this, "Error during HTTP get", cause);
    -			throw (cause instanceof IOException)
    -					? (IOException) cause
    +			throw (cause instanceof IOException) ? (IOException) cause
     					: new IOException("Error during HTTP get", cause);
     		}
     		finally {
    
  • Ghidra/Framework/FileSystem/src/main/java/ghidra/framework/client/ClientUtil.java+2 1 modified
    @@ -26,6 +26,7 @@
     import javax.security.auth.callback.*;
     import javax.security.auth.login.LoginException;
     
    +import generic.hash.HashUtilities;
     import ghidra.framework.model.ServerInfo;
     import ghidra.framework.remote.*;
     import ghidra.framework.remote.security.SSHKeyManager;
    @@ -444,7 +445,7 @@ else if (callback instanceof AnonymousCallback) {
     	static void processSignatureCallback(String serverName, SignatureCallback sigCb)
     			throws IOException {
     		try {
    -			SignedToken signedToken = ApplicationKeyManagerUtils
    +			SignedToken signedToken = DefaultKeyManagerFactory
     					.getSignedToken(sigCb.getRecognizedAuthorities(), sigCb.getToken());
     			sigCb.sign(signedToken.certChain, signedToken.signature);
     			Msg.info(ClientUtil.class, "PKI Authenticating to " + serverName + " as user '" +
    
  • Ghidra/Framework/FileSystem/src/main/java/ghidra/framework/client/HeadlessClientAuthenticator.java+2 2 modified
    @@ -27,7 +27,7 @@
     import ghidra.framework.remote.AnonymousCallback;
     import ghidra.framework.remote.SSHSignatureCallback;
     import ghidra.framework.remote.security.SSHKeyManager;
    -import ghidra.net.ApplicationKeyManagerFactory;
    +import ghidra.net.DefaultKeyManagerFactory;
     import ghidra.util.Msg;
     
     /**
    @@ -169,7 +169,7 @@ public static void installHeadlessClientAuthenticator(String username, String ke
     			}
     			catch (InvalidKeyException e) { // keyfile is not a valid SSH private key format
     				// does not appear to be an SSH private key - try PKI keystore parse
    -				if (ApplicationKeyManagerFactory.setKeyStore(keystorePath, false)) {
    +				if (DefaultKeyManagerFactory.setDefaultKeyStore(keystorePath, false)) {
     					success = true;
     					Msg.info(HeadlessClientAuthenticator.class,
     						"Loaded PKI keystore: " + keystorePath);
    
  • Ghidra/Framework/FileSystem/src/main/java/ghidra/framework/client/PasswordClientAuthenticator.java+2 2 modified
    @@ -23,7 +23,7 @@
     
     import ghidra.framework.remote.AnonymousCallback;
     import ghidra.framework.remote.SSHSignatureCallback;
    -import ghidra.net.ApplicationKeyManagerFactory;
    +import ghidra.net.DefaultKeyManagerFactory;
     
     /**
      * <code>PasswordClientAuthenticator</code> provides a fixed username/password 
    @@ -38,7 +38,7 @@
      * for accessing SSH keys or server password authentication.  In such headless situations,
      * the PKI certificate path/password should be specified via a property since it is unlikely
      * that the same password will apply.
    - * @see ApplicationKeyManagerFactory 
    + * @see DefaultKeyManagerFactory 
      */
     public class PasswordClientAuthenticator implements ClientAuthenticator {
     
    
  • Ghidra/Framework/FileSystem/src/main/java/ghidra/framework/client/RepositoryServerAdapter.java+3 3 modified
    @@ -4,9 +4,9 @@
      * Licensed under the Apache License, Version 2.0 (the "License");
      * you may not use this file except in compliance with the License.
      * You may obtain a copy of the License at
    - * 
    + *
      *      http://www.apache.org/licenses/LICENSE-2.0
    - * 
    + *
      * Unless required by applicable law or agreed to in writing, software
      * distributed under the License is distributed on an "AS IS" BASIS,
      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    @@ -486,7 +486,7 @@ public synchronized String[] getAllUsers() throws IOException, NotConnectedExcep
     	 * @throws IOException if user data can't be written to file
     	 * @throws NotConnectedException if server connection is down (user already informed)
     	 * @see ghidra.framework.remote.RemoteRepositoryServerHandle#setPassword(char[])
    -	 * @see ghidra.util.HashUtilities#getSaltedHash(String, char[])  HashUtilities.getSaltedHash("SHA-256", char[])
    +	 * @see generic.hash.HashUtilities#getSaltedHash(String, char[])  HashUtilities.getSaltedHash("SHA-256", char[])
     	 */
     	public synchronized boolean setPassword(char[] saltedSHA256PasswordHash)
     			throws IOException, NotConnectedException {
    
  • Ghidra/Framework/FileSystem/src/main/java/ghidra/framework/client/ServerConnectTask.java+4 5 modified
    @@ -38,7 +38,7 @@
     import ghidra.framework.Application;
     import ghidra.framework.model.ServerInfo;
     import ghidra.framework.remote.*;
    -import ghidra.net.ApplicationKeyManagerFactory;
    +import ghidra.net.DefaultKeyManagerFactory;
     import ghidra.util.Msg;
     import ghidra.util.exception.CancelledException;
     import ghidra.util.task.*;
    @@ -130,7 +130,7 @@ private static Subject getLocalUserSubject() {
     
     	private static boolean isSSLHandshakeCancelled(SSLHandshakeException e) throws IOException {
     		if (e.getMessage().indexOf("bad_certificate") > 0) {
    -			if (ApplicationKeyManagerFactory.getPreferredKeyStore() == null) {
    +			if (DefaultKeyManagerFactory.getPreferredKeyStore() == null) {
     				throw new IOException("User PKI Certificate not installed", e);
     			}
     			// assume user cancelled connect attempt when prompted for cert password
    @@ -291,13 +291,12 @@ else if (pkiSignatureCb != null) {
     							// if anonymous access allowed, let server validate certificate
     							// first and assume anonymous access if user unknown but cert is valid
     
    -							if (!ApplicationKeyManagerFactory.initialize()) {
    +							if (!DefaultKeyManagerFactory.initialize()) {
     								throw new IOException(
     									"Client PKI certificate has not been installed");
     							}
     
    -							if (ApplicationKeyManagerFactory
    -									.usingGeneratedSelfSignedCertificate()) {
    +							if (DefaultKeyManagerFactory.usingGeneratedSelfSignedCertificate()) {
     								Msg.warn(this,
     									"Server connect - client is using self-signed PKI certificate");
     							}
    
  • Ghidra/Framework/FileSystem/src/main/java/ghidra/framework/remote/RepositoryServerHandle.java+3 3 modified
    @@ -4,9 +4,9 @@
      * Licensed under the Apache License, Version 2.0 (the "License");
      * you may not use this file except in compliance with the License.
      * You may obtain a copy of the License at
    - * 
    + *
      *      http://www.apache.org/licenses/LICENSE-2.0
    - * 
    + *
      * Unless required by applicable law or agreed to in writing, software
      * distributed under the License is distributed on an "AS IS" BASIS,
      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    @@ -104,7 +104,7 @@ public interface RepositoryServerHandle {
     	 * @param saltedSHA256PasswordHash SHA256 salted password hash
     	 * @return true if password changed
     	 * @throws IOException if an IO error occurs
    -	 * @see ghidra.util.HashUtilities#getSaltedHash(String, char[])  HashUtilities.getSaltedHash("SHA-256", char[])
    +	 * @see generic.hash.HashUtilities#getSaltedHash(String, char[])  HashUtilities.getSaltedHash("SHA-256", char[])
     	 */
     	boolean setPassword(char[] saltedSHA256PasswordHash) throws IOException;
     
    
  • Ghidra/Framework/FileSystem/src/main/java/ghidra/util/MD5Utilities.java+5 7 modified
    @@ -4,9 +4,9 @@
      * Licensed under the Apache License, Version 2.0 (the "License");
      * you may not use this file except in compliance with the License.
      * You may obtain a copy of the License at
    - * 
    + *
      *      http://www.apache.org/licenses/LICENSE-2.0
    - * 
    + *
      * Unless required by applicable law or agreed to in writing, software
      * distributed under the License is distributed on an "AS IS" BASIS,
      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    @@ -18,6 +18,8 @@
     import java.io.*;
     import java.util.List;
     
    +import generic.hash.HashUtilities;
    +
     public class MD5Utilities {
     
     	public static final int SALT_LENGTH = HashUtilities.SALT_LENGTH;
    @@ -54,11 +56,7 @@ public static char[] getSaltedMD5Hash(char[] salt, char[] msg) {
     	 * returned as a prefix to the hash
     	 */
     	public static char[] getSaltedMD5Hash(char[] msg) {
    -		char[] salt = new char[HashUtilities.SALT_LENGTH];
    -		for (int i = 0; i < salt.length; i++) {
    -			salt[i] = HashUtilities.getRandomLetterOrDigit();
    -		}
    -		return getSaltedMD5Hash(salt, msg);
    +		return HashUtilities.getSaltedHash(HashUtilities.MD5_ALGORITHM, msg);
     	}
     
     	/**
    
  • Ghidra/Framework/Generic/src/main/java/generic/hash/HashUtilities.java+4 3 renamed
    @@ -4,16 +4,16 @@
      * Licensed under the Apache License, Version 2.0 (the "License");
      * you may not use this file except in compliance with the License.
      * You may obtain a copy of the License at
    - * 
    + *
      *      http://www.apache.org/licenses/LICENSE-2.0
    - * 
    + *
      * Unless required by applicable law or agreed to in writing, software
      * distributed under the License is distributed on an "AS IS" BASIS,
      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      * See the License for the specific language governing permissions and
      * limitations under the License.
      */
    -package ghidra.util;
    +package generic.hash;
     
     import java.io.*;
     import java.security.MessageDigest;
    @@ -22,6 +22,7 @@
     import java.util.List;
     
     import generic.random.SecureRandomFactory;
    +import ghidra.util.NumericUtilities;
     
     public class HashUtilities {
     
    
  • Ghidra/Framework/Generic/src/main/java/ghidra/net/ApplicationKeyManagerFactory.java+95 508 modified
    @@ -4,9 +4,9 @@
      * Licensed under the Apache License, Version 2.0 (the "License");
      * you may not use this file except in compliance with the License.
      * You may obtain a copy of the License at
    - * 
    + *
      *      http://www.apache.org/licenses/LICENSE-2.0
    - * 
    + *
      * Unless required by applicable law or agreed to in writing, software
      * distributed under the License is distributed on an "AS IS" BASIS,
      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    @@ -15,74 +15,32 @@
      */
     package ghidra.net;
     
    -import java.io.FileNotFoundException;
    -import java.io.IOException;
    -import java.net.Socket;
    +import java.io.*;
     import java.security.*;
    +import java.security.cert.Certificate;
     import java.security.cert.CertificateException;
     import java.security.cert.X509Certificate;
     import java.util.*;
     
     import javax.net.ssl.*;
    -import javax.security.auth.x500.X500Principal;
    -
    -import org.apache.commons.lang3.StringUtils;
     
    -import ghidra.framework.preferences.Preferences;
    +import generic.hash.HashUtilities;
     import ghidra.security.KeyStorePasswordProvider;
     import ghidra.util.Msg;
    -import ghidra.util.SystemUtilities;
     import ghidra.util.exception.CancelledException;
     
     /**
    - * <code>ApplicationKeyManagerFactory</code> provides application keystore management
    - * functionality and the ability to generate X509KeyManager's for use with an SSLContext
    - * or other PKI related operations.  Access to keystore data (other than keystore path)
    - * is restricted to package access.  Certain public operations are exposed via the
    - * {@link ApplicationKeyManagerUtils} class.
    + * {@link ApplicationKeyManagerFactory} provides a factory for using and caching X509 keystores.
      */
     public class ApplicationKeyManagerFactory {
     
    -	/**
    -	 * Keystore path system property or user preference.  Setting the system
    -	 * property will take precedence over the user preference.
    -	 */
    -	public static final String KEYSTORE_PATH_PROPERTY = "ghidra.keystore";
    -
    -	/**
    -	 * Password system property may be set.  If set, this password will be used
    -	 * when accessing the keystore before attempting to use <code>customPasswordProvider</code>
    -	 * if it has been set.
    -	 */
    -	public static final String KEYSTORE_PASSWORD_PROPERTY = "ghidra.password";
    -
    -	public static final String DEFAULT_PASSWORD = "changeme";
    -
    -	private static final int SELF_SIGNED_DURATION_DAYS = 2 * 365; // 2-years
    -
     	private static KeyStorePasswordProvider customPasswordProvider;
    -	private static X500Principal defaultIdentity;
    -	private static List<String> subjectAlternativeNames;
     
    -	private static ApplicationKeyManagerFactory instance;
    +	// X509KeyManager cached keyed by file hash concatenated with its canonical path
    +	private static HashMap<String, X509KeyManager> keyStoreCache = new HashMap<>();
     
    -	/**
    -	 * Get ApplicationKeyManager singleton
    -	 * @return application X509KeyManager
    -	 */
    -	static synchronized ApplicationKeyManagerFactory getInstance() {
    -		if (instance == null) {
    -			instance = new ApplicationKeyManagerFactory();
    -		}
    -		return instance;
    -	}
    -
    -	/**
    -	 * get the single key manager instance associated with the factory.
    -	 * @return key manager instance
    -	 */
    -	private static ApplicationKeyManager getKeyManagerWrapper() {
    -		return getInstance().keyManagerWrapper;
    +	private ApplicationKeyManagerFactory() {
    +		// no construct
     	}
     
     	/**
    @@ -94,220 +52,49 @@ public static synchronized void setKeyStorePasswordProvider(KeyStorePasswordProv
     	}
     
     	/**
    -	 * Prune path to trim leading and trailing white space. A null will be
    -	 * returned if the pruned path is null or the empty string.
    -	 *
    -	 * @param path
    -	 * @return pruned path or null if path was null or pruned path was the empty
    -	 *         string
    +	 * Clear all cached key managers.
    +	 * NOTE: This is primarily intended for test use only.
     	 */
    -	private static String prunePath(String path) {
    -		if (path != null) {
    -			path = path.trim();
    -			if (path.length() == 0) {
    -				path = null;
    -			}
    -		}
    -		return path;
    +	public static synchronized void clearKeyManagerCache() {
    +		keyStoreCache.clear();
     	}
     
     	/**
    -	 * Set user keystore file path (e.g., certificate file with private key).
    -	 * This method will have no effect if the keystore had been set via the system
    -	 * property and an error will be displayed.  Otherwise, the keystore will
    -	 * be updated and the key manager re-initialized.  The user preference will be
    -	 * updated unless a failure occurred while attempting to open the keystore.
    -	 * This change will take immediate effect for the current executing application,
    -	 * however, it may still be superseded by a system property setting when running
    -	 * the application in the future. See {@link #getKeyStore()}.
    -	 * @param path keystore file path or null to clear current key store and preference.
    -	 * @param savePreference if true will be saved as user preference
    -	 * @return true if successful else false if error occured (see log).
    +	 * Get key manager for specified JKS or PKCS12 keystore file path.  The user may be prompted
    +	 * for a password if required which will block the invocation of this synchronized method.  
    +	 * If successfully opened, the resulting key manager instance will be cached for subsequent 
    +	 * re-use of the same keystore.
    +	 * 
    +	 * @param keystorePath protected keystore path
    +	 * @param defaultPasswd default password (e.g., supplied by property) or null
    +	 * @return key manager
    +	 * @throws CancelledException password entry was cancelled by user
    +	 * @throws KeyStoreException error occurred opening/processing keystore
     	 */
    -	public static synchronized boolean setKeyStore(String path, boolean savePreference) {
    -
    -		if (System.getProperty(KEYSTORE_PATH_PROPERTY) != null) {
    -			Msg.showError(ApplicationKeyManagerFactory.class, null, "Set KeyStore Failed",
    -				"PKI KeyStore was set via system property and can not be changed");
    -			return false;
    -		}
    +	public synchronized static X509KeyManager getKeyManager(String keystorePath,
    +			String defaultPasswd) throws CancelledException, KeyStoreException {
     
    -		path = prunePath(path);
    +		String hashKey;
     
     		try {
    -			boolean keyInitialized = getKeyManagerWrapper().init(path);
    -
    -			if (savePreference && (path == null || keyInitialized)) {
    -				Preferences.setProperty(KEYSTORE_PATH_PROPERTY, path);
    -				Preferences.store();
    +			if (PKIUtils.detectKeyStoreType(keystorePath) == null) {
    +				throw new KeyStoreException("Unsupported PKI key store file type: " + keystorePath);
     			}
    -			return keyInitialized;
    -		}
    -		catch (CancelledException e) {
    -			// ignore - keystore left unchanged
    -			return false;
    -		}
    -	}
    -
    -	/**
    -	 * Get the keystore path associated with the active key manager or the
    -	 * preferred keystore path if not yet initialized.
    -	 */
    -	public static synchronized String getKeyStore() {
    -		return getKeyManagerWrapper().getKeyStore();
    -	}
    +			// Obtain canonical path for cache use
    +			File keystoreFile = new File(keystorePath);
    +			keystorePath = (keystoreFile).getCanonicalPath();
     
    -	/**
    -	 * If the system property <i>ghidra.keystore</i> takes precedence in establishing 
    -	 * the keystore.  If using a GUI and the system property has not been set, the 
    -	 * user preference with the same name will be used.
    -	 * @return active keystore path or null if currently not running with a keystore or
    -	 * one has not been set.
    -	 */
    -	public static synchronized String getPreferredKeyStore() {
    -		String path = prunePath(System.getProperty(KEYSTORE_PATH_PROPERTY));
    -		if (path == null && !SystemUtilities.isInHeadlessMode()) {
    -			path = prunePath(Preferences.getProperty(KEYSTORE_PATH_PROPERTY));
    -		}
    -		return path;
    -	}
    -
    -	/**
    -	 * Determine if active key manager is utilizing a generated self-signed certificate.
    -	 * @return true if using self-signed certificate.
    -	 */
    -	public static synchronized boolean usingGeneratedSelfSignedCertificate() {
    -		return getKeyManagerWrapper().usingGeneratedSelfSignedCertificate();
    -	}
    -
    -	/**
    -	 * Set the default self-signed principal identity to be used during initialization
    -	 * if no keystore defined.  Current application key manager will be invalidated.
    -	 * (NOTE: this is intended for server use only when client will not be performing
    -	 * CA validation).
    -	 * @param identity if not null and a KeyStore path has not be set, this
    -	 * identity will be used to generate a self-signed certificate and private key
    -	 */
    -	public synchronized static void setDefaultIdentity(X500Principal identity) {
    -		defaultIdentity = identity;
    -		getKeyManagerWrapper().invalidateKey();
    -	}
    +			hashKey = HashUtilities.getHash(HashUtilities.MD5_ALGORITHM, keystoreFile) + "_" +
    +				keystorePath;
     
    -	/**
    -	 * Add the optional self-signed subject alternative name to be used during initialization
    -	 * if no keystore defined.  Current application key manager will be invalidated.
    -	 * (NOTE: this is intended for server use only when client will not be performing
    -	 * CA validation).
    -	 * @param subjectAltName name to be added to the current list of alternative subject names.
    -	 * A null value will clear all names currently set.  
    -	 * name will be used to generate a self-signed certificate and private key
    -	 */
    -	public synchronized static void addSubjectAlternativeName(String subjectAltName) {
    -		if (subjectAltName == null) {
    -			subjectAlternativeNames = null;
    -		}
    -		else {
    -			if (subjectAlternativeNames == null) {
    -				subjectAlternativeNames = new ArrayList<>();
    +			X509KeyManager keyManager = keyStoreCache.get(hashKey);
    +			if (keyManager != null) {
    +				return keyManager;
     			}
    -			subjectAlternativeNames.add(subjectAltName);
     		}
    -		getKeyManagerWrapper().invalidateKey();
    -	}
    -
    -	/**
    -	 * Get the current list of subject alternative names to be used for a self-signed certificate
    -	 * if no keystore defined.
    -	 * @return list of subject alternative names to be used for a self-signed certificate
    -	 * if no keystore defined.
    -	 */
    -	public synchronized static List<String> getSubjectAlternativeName() {
    -		return Collections.unmodifiableList(subjectAlternativeNames);
    -	}
    -
    -	/**
    -	 * Initialize key manager if needed.  Doing this explicitly independent of an SSL connection
    -	 * allows application to bail before initiating connection.  This will get handshake failure
    -	 * if user forgets keystore password or other keystore problem.
    -	 * @return true if key manager initialized, otherwise false
    -	 */
    -	public synchronized static boolean initialize() {
    -		try {
    -			return getKeyManagerWrapper().init();
    +		catch (IOException e) {
    +			throw new KeyStoreException("Failed to examine keystore: " + keystorePath, e);
     		}
    -		catch (CancelledException e) {
    -			return false;
    -		}
    -	}
    -
    -	/**
    -	 * Invalidate the key managers associated with this factory
    -	 */
    -	public synchronized static void invalidateKeyManagers() {
    -		getKeyManagerWrapper().invalidateKey();
    -	}
    -
    -	// Factory maintains a single X509 key manager
    -	private ApplicationKeyManager keyManagerWrapper = new ApplicationKeyManager();
    -
    -	/**
    -	 * <code>ApplicationKeyManagerFactory</code> constructor
    -	 */
    -	private ApplicationKeyManagerFactory() {
    -	}
    -
    -	/**
    -	 * Get key managers
    -	 * @return key managers
    -	 */
    -	KeyManager[] getKeyManagers() {
    -		return new KeyManager[] { keyManagerWrapper };
    -	}
    -
    -	/**
    -	 * <code>ProtectedKeyStoreData</code> provides a container for a keystore
    -	 * which has been successfully accessed using the specified password.
    -	 */
    -	private static class ProtectedKeyStoreData {
    -		KeyStore keyStore;
    -		char[] password;
    -
    -		ProtectedKeyStoreData(KeyStore keyStore, char[] password) {
    -			this.keyStore = keyStore;
    -			this.password = password != null ? password.clone() : null;
    -		}
    -
    -		/**
    -		 * Dispose this keystore data wrapper and the retained password
    -		 */
    -		void dispose() {
    -			if (password != null) {
    -				Arrays.fill(password, ' ');
    -			}
    -			keyStore = null;
    -		}
    -
    -		@Override
    -		protected void finalize() throws Throwable {
    -			dispose();
    -			super.finalize();
    -		}
    -	}
    -
    -	/**
    -	 * Get protected keystore data for specified keystorePath.  Caller is responsible for
    -	 * properly disposing returned object.
    -	 * @param keystorePath protected keystore path
    -	 * @return protected keystore data
    -	 * @throws CancelledException password entry was cancelled by user
    -	 * @throws KeyStoreException error occurred opening/processing keystore
    -	 */
    -	private static ProtectedKeyStoreData getProtectedKeyStoreData(String keystorePath)
    -			throws CancelledException, KeyStoreException {
    -
    -		Msg.info(ApplicationKeyManagerFactory.class, "Using certificate keystore: " + keystorePath);
    -
    -		String keystorePwd = System.getProperty(KEYSTORE_PASSWORD_PROPERTY);
     
     		int tryCount = 0;
     
    @@ -319,20 +106,12 @@ private static ProtectedKeyStoreData getProtectedKeyStoreData(String keystorePat
     					// try no password first
     				}
     				else if (tryCount == 1) {
    -					// try default password
    -					Msg.debug(ApplicationKeyManagerFactory.class,
    -						"Attempting to load keystore without password...");
    -					password = DEFAULT_PASSWORD.toCharArray();
    -				}
    -				else if (tryCount == 2) {
     					// try specified password
    -					if (keystorePwd != null) {
    -						Msg.debug(ApplicationKeyManagerFactory.class,
    -							"Attempting to load keystore with property-based password...");
    -						password = keystorePwd.toCharArray();
    +					if (defaultPasswd != null) {
    +						password = defaultPasswd.toCharArray();
     					}
     					else {
    -						// no system property password provided
    +						// no default password was provided
     						++tryCount;
     						continue;
     					}
    @@ -341,7 +120,7 @@ else if (customPasswordProvider != null) {
     					disposePassword(oldPassword);
     					oldPassword = password;
     					password =
    -						customPasswordProvider.getKeyStorePassword(keystorePath, tryCount != 3);
    +						customPasswordProvider.getKeyStorePassword(keystorePath, tryCount != 2);
     					if (password == null) {
     						throw new CancelledException();
     					}
    @@ -358,24 +137,24 @@ else if (customPasswordProvider != null) {
     				}
     				++tryCount;
     
    -				// we only support a single password for both keystore and private key
    -				KeyStore keyStore = ApplicationKeyStore.getKeyStoreInstance(keystorePath, password);
    -				return new ProtectedKeyStoreData(keyStore, password);
    +				// NOTE: we only support a single password for both keystore and private key
    +				KeyStore keyStore = PKIUtils.getKeyStoreInstance(keystorePath, password);
    +				X509KeyManager keyManager = getKeyManagerFromKeyStore(keyStore, password);
    +				keyStoreCache.put(hashKey, keyManager);
    +				return keyManager;
     			}
    -			catch (NoSuchAlgorithmException | CertificateException | FileNotFoundException e) {
    +			catch (UnrecoverableKeyException | NoSuchAlgorithmException | CertificateException
    +					| FileNotFoundException e) {
     				throw new KeyStoreException("Failed to process keystore: " + keystorePath, e);
     			}
     			catch (KeyStoreException | IOException e) {
     				// Java Bug: JDK-6974037 : PKCS12 Keystore load with invalid passwords generates different exceptions
     				Exception ioException = getIOException(e);
    -				if (ioException != null) {
    -					// Assume all IOExceptions are the result of improperly decrypted keystore
    -					// since arbitrary and inconsistent errors are produced when attempting to 
    -					// load an encrypted keystore without a password or with the wrong password.
    -					continue;
    +				if (ioException != null &&
    +					ioException.getCause() instanceof UnrecoverableKeyException) {
    +					continue; // Assume incorrect password was specified
     				}
    -				throw new KeyStoreException(
    -					"Failed to process keystore (" + tryCount + "): " + keystorePath, e);
    +				throw new KeyStoreException("Failed to open keystore: " + keystorePath, e);
     			}
     			finally {
     				disposePassword(oldPassword);
    @@ -385,6 +164,47 @@ else if (customPasswordProvider != null) {
     		throw new KeyStoreException("Failed to unlock key storage: " + keystorePath);
     	}
     
    +	/**
    +	 * Get key manager for specified JKS or PKCS12 keystore. The keystore must only contain a 
    +	 * single X509 certificate and corresponding private key which has a usage of digital signing.
    +	 * @param keyStore JKS or PKCS12 keystore file
    +	 * @param password password for accessing keystore and private key.
    +	 * @return X509 key manager instance
    +	 * @throws NoSuchAlgorithmException if the specified algorithm is not available from the 
    +	 * 			specified provider.
    +	 * @throws UnrecoverableKeyException if the key cannot be recovered
    +	 *          (e.g. the given password is wrong).
    +	 * @throws KeyStoreException if a general failure occurs while accessing keystore
    +	 */
    +	static X509KeyManager getKeyManagerFromKeyStore(KeyStore keyStore, char[] password)
    +			throws UnrecoverableKeyException, NoSuchAlgorithmException, KeyStoreException {
    +
    +		// Assume cert of interest is the first one
    +		Enumeration<String> aliases = keyStore.aliases();
    +		if (!aliases.hasMoreElements()) {
    +			throw new KeyStoreException("PKI key store is empty");
    +		}
    +		Certificate certificate = keyStore.getCertificate(aliases.nextElement());
    +		if (!(certificate instanceof X509Certificate x509Cert)) {
    +			throw new KeyStoreException("PKI X509 Certificate not found");
    +		}
    +		boolean[] keyUsage = x509Cert.getKeyUsage();
    +		if (!keyUsage[0]) {
    +			throw new KeyStoreException("PKI key store must contain Digital Signing certificate");
    +		}
    +
    +		KeyManagerFactory kmf =
    +			KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
    +		kmf.init(keyStore, password);
    +
    +		// Assume that one keystore will produce at most one KeyManager
    +		KeyManager[] keyManagers = kmf.getKeyManagers();
    +		if (keyManagers.length == 1 && (keyManagers[0] instanceof X509KeyManager)) {
    +			return (X509KeyManager) keyManagers[0];
    +		}
    +		throw new KeyStoreException("Unsupported keystore");
    +	}
    +
     	private static void disposePassword(char[] password) {
     		if (password != null) {
     			Arrays.fill(password, (char) 0);
    @@ -403,237 +223,4 @@ private static IOException getIOException(Exception e) {
     		return null;
     	}
     
    -	/**
    -	 * <code>ApplicationKeyManager</code> provides a wrapper for the X509 wrappedKeyManager whose
    -	 * instantiation is delayed until needed.  When a wrapper method is first invoked, the
    -	 * {@link ApplicationKeyManagerFactory#init()} method is called to open the keystore
    -	 * (which may require a password prompt) and establish the underlying X509KeyManager.
    -	 */
    -	private class ApplicationKeyManager extends X509ExtendedKeyManager {
    -
    -		private X509KeyManager wrappedKeyManager;
    -		private String keystorePath;
    -		private boolean isSelfSigned = false;
    -
    -		@Override
    -		public String chooseEngineServerAlias(String keyType, Principal[] issuers,
    -				SSLEngine engine) {
    -			return super.chooseEngineServerAlias(keyType, issuers, engine);
    -		}
    -
    -		@Override
    -		public String chooseEngineClientAlias(String[] keyType, Principal[] issuers,
    -				SSLEngine engine) {
    -			return super.chooseEngineClientAlias(keyType, issuers, engine);
    -		}
    -
    -		@Override
    -		public synchronized String chooseClientAlias(String[] keyType, Principal[] issuers,
    -				Socket socket) {
    -			try {
    -				init();
    -			}
    -			catch (CancelledException e) {
    -				// ignore
    -			}
    -			if (wrappedKeyManager == null) {
    -				return null;
    -			}
    -			return wrappedKeyManager.chooseClientAlias(keyType, issuers, socket);
    -		}
    -
    -		@Override
    -		public synchronized String chooseServerAlias(String keyType, Principal[] issuers,
    -				Socket socket) {
    -			try {
    -				init();
    -			}
    -			catch (CancelledException e) {
    -				// ignore
    -			}
    -			if (wrappedKeyManager == null) {
    -				return null;
    -			}
    -			return wrappedKeyManager.chooseServerAlias(keyType, issuers, socket);
    -		}
    -
    -		@Override
    -		public String[] getClientAliases(String keyType, Principal[] issuers) {
    -			try {
    -				init();
    -			}
    -			catch (CancelledException e) {
    -				// ignore
    -			}
    -			if (wrappedKeyManager == null) {
    -				return null;
    -			}
    -			return wrappedKeyManager.getClientAliases(keyType, issuers);
    -		}
    -
    -		@Override
    -		public String[] getServerAliases(String keyType, Principal[] issuers) {
    -			try {
    -				init();
    -			}
    -			catch (CancelledException e) {
    -				// ignore
    -			}
    -			if (wrappedKeyManager == null) {
    -				return null;
    -			}
    -			return wrappedKeyManager.getServerAliases(keyType, issuers);
    -		}
    -
    -		@Override
    -		public X509Certificate[] getCertificateChain(String alias) {
    -			if (wrappedKeyManager == null) {
    -				return null;
    -			}
    -			return wrappedKeyManager.getCertificateChain(alias);
    -		}
    -
    -		@Override
    -		public PrivateKey getPrivateKey(String alias) {
    -			if (wrappedKeyManager == null) {
    -				return null;
    -			}
    -			return wrappedKeyManager.getPrivateKey(alias);
    -		}
    -
    -		/**
    -		 * Invalidate the active keystore and key manager
    -		 */
    -		private synchronized void invalidateKey() {
    -			wrappedKeyManager = null;
    -			keystorePath = null;
    -			isSelfSigned = false;
    -		}
    -
    -		/**
    -		 * Return active keystore path or preferred keystore path if not yet initialized.
    -		 * @return active keystore path or preferred keystore path if not yet initialized.
    -		 */
    -		private synchronized String getKeyStore() {
    -			return wrappedKeyManager != null ? keystorePath : getPreferredKeyStore();
    -		}
    -
    -		/**
    -		 * Determine if active key manager is utilizing a generated self-signed certificate.
    -		 * @return true if using self-signed certificate.
    -		 */
    -		private synchronized boolean usingGeneratedSelfSignedCertificate() {
    -			return wrappedKeyManager != null && isSelfSigned;
    -		}
    -
    -		/**
    -		 * Initialize the x509KeyManager associated with the active keystore setting.
    -		 * If the <code>x509KeyManager</code> already exists, this method has no affect.  If the
    -		 * <code>keystorePath</code> has not already been set, the <code>getPreferredKeyStore()</code>
    -		 * method will be invoked to obtain the keystore which should be used in establishing the
    -		 * <code>wrappedKeyManager</code>.  If no keystore has been identified and the Default Identity
    -		 * has been set, a self-signed certificate will be generated.  If nothing has been set, the
    -		 * wrappedKeyManager will remain null and false will be returned.  If an error occurs it
    -		 * will be logged and key managers will remain uninitialized.
    -		 * @return true if key manager initialized successfully or was previously initialized, else
    -		 * false if keystore path has not been set and default identity for self-signed certificate
    -		 * has not be established (see {@link ApplicationKeyManagerFactory#setDefaultIdentity(X500Principal)}).
    -		 * @throws CancelledException user cancelled keystore password entry request
    -		 */
    -		private synchronized boolean init() throws CancelledException {
    -			if (wrappedKeyManager != null) {
    -				return true;
    -			}
    -			return init(getPreferredKeyStore());
    -		}
    -
    -		/**
    -		 * Initialize the x509KeyManager.
    -		 * If the <code>x509KeyManager</code> already exists for the specified keystore path,
    -		 * this method has no affect.  If no keystore has been identified and the Default Identity
    -		 * has been set, a self-signed certificate will be generated.  If nothing has been set, the
    -		 * wrappedKeyManager will remain null and false will be returned.  If an error occurs it
    -		 * will be logged and key managers will remain uninitialized.
    -		 * @param newKeystorePath specifies the keystore to be opened or null for no keystore
    -		 * @return true if key manager initialized successfully or was previously initialized, else
    -		 * false if new keystore path was not specified and default identity for self-signed certificate
    -		 * has not be established (see {@link ApplicationKeyManagerFactory#setDefaultIdentity(X500Principal)}).
    -		 * @throws CancelledException user cancelled keystore password entry request
    -		 */
    -		private synchronized boolean init(String newKeystorePath) throws CancelledException {
    -
    -			if (wrappedKeyManager != null) {
    -				if (StringUtils.equals(keystorePath, newKeystorePath)) {
    -					return true;
    -				}
    -				invalidateKey();
    -			}
    -
    -			ProtectedKeyStoreData keystoreData = null;
    -			try {
    -				if (newKeystorePath != null && newKeystorePath.length() != 0) {
    -					keystoreData = getProtectedKeyStoreData(newKeystorePath);
    -				}
    -				else if (defaultIdentity != null) {
    -					// use self-signed keystore as fallback (intended for server use only)
    -					Msg.info(this, "Using self-signed certificate: " + defaultIdentity.getName());
    -					char[] pwd = DEFAULT_PASSWORD.toCharArray();
    -					KeyStore selfSignedKeyStore =
    -						ApplicationKeyManagerUtils.createKeyStore("defaultSigKey",
    -							defaultIdentity.getName(), SELF_SIGNED_DURATION_DAYS, null, null, "JKS",
    -							subjectAlternativeNames, pwd);
    -					keystoreData = new ProtectedKeyStoreData(selfSignedKeyStore, pwd);
    -					isSelfSigned = true;
    -				}
    -				else {
    -					return false;
    -				}
    -
    -				ApplicationKeyStore.logCerts(keystoreData.keyStore);
    -
    -				KeyManagerFactory kmf =
    -					KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
    -				kmf.init(keystoreData.keyStore, keystoreData.password);
    -
    -				// Assume that one keystore will produce at most one KeyManager
    -				KeyManager[] keyManagers = kmf.getKeyManagers();
    -				if (keyManagers.length == 1 && (keyManagers[0] instanceof X509KeyManager)) {
    -					wrappedKeyManager = (X509KeyManager) keyManagers[0];
    -					keystorePath = newKeystorePath; // update current keystore path
    -					return true;
    -				}
    -
    -				isSelfSigned = false;
    -
    -				if (keyManagers.length == 0) {
    -					Msg.showError(this, null, "PKI Keystore Failure",
    -						"Failed to create PKI key manager: failed to process keystore (no keys processed)");
    -				}
    -				else if (keyManagers.length == 1) {
    -					Msg.showError(this, null, "PKI Keystore Failure",
    -						"Failed to create PKI key manager: failed to process keystore (expected X.509)");
    -				}
    -				else {
    -					// Unexpected condition
    -					Msg.showError(this, null, "PKI Keystore Failure",
    -						"Failed to create PKI key manager: unsupported keystore produced multiple KeyManagers");
    -				}
    -			}
    -			catch (CancelledException e) {
    -				throw e;
    -			}
    -			catch (Exception e) {
    -				Msg.showError(this, null, "PKI Keystore Failure",
    -					"Failed to create PKI key manager: " + e.getMessage(), e);
    -			}
    -			finally {
    -				if (keystoreData != null) {
    -					keystoreData.dispose();
    -					keystoreData = null;
    -				}
    -			}
    -			return false;
    -		}
    -	}
    -
     }
    
  • Ghidra/Framework/Generic/src/main/java/ghidra/net/ApplicationKeyStore.java+0 244 removed
    @@ -1,244 +0,0 @@
    -/* ###
    - * IP: GHIDRA
    - *
    - * Licensed under the Apache License, Version 2.0 (the "License");
    - * you may not use this file except in compliance with the License.
    - * You may obtain a copy of the License at
    - *
    - *      http://www.apache.org/licenses/LICENSE-2.0
    - *
    - * Unless required by applicable law or agreed to in writing, software
    - * distributed under the License is distributed on an "AS IS" BASIS,
    - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    - * See the License for the specific language governing permissions and
    - * limitations under the License.
    - */
    -package ghidra.net;
    -
    -import java.io.*;
    -import java.security.*;
    -import java.security.cert.*;
    -import java.security.cert.Certificate;
    -import java.util.Date;
    -import java.util.Enumeration;
    -
    -import javax.security.auth.x500.X500Principal;
    -
    -import ghidra.util.Msg;
    -
    -/**
    - * <code>ApplicationKeyStore</code> provides the ability to read X.509 certificates and 
    - * keystores in various formats. Certificate files (e.g., cacerts) may be in a standard
    - * X.509 form (*.pem, *.crt, *.cer, *.der) or Java JKS (*.jks) form, while keystores 
    - * for client/server may be in a PKCS12 form (*.p12, *.pks, *.pfx) or Java JKS (*.jks) form.
    - */
    -public class ApplicationKeyStore {
    -
    -	private ApplicationKeyStore() {
    -		// no instantiation - static methods only
    -	}
    -
    -	/**
    -	 * Load the specified X.509 certificate authority store in a standard
    -	 * X.509 form (*.pem, *.crt, *.cer, *.der) or Java JKS (*.jks) form.
    -	 * @param cacertsPath certificate store file path
    -	 * @return KeyStore containing ingested certificates
    -	 * @throws IOException
    -	 * @throws KeyStoreException
    -	 * @throws NoSuchAlgorithmException
    -	 * @throws CertificateException
    -	 */
    -	public static KeyStore getCertificateStoreInstance(String cacertsPath)
    -			throws IOException, KeyStoreException, NoSuchAlgorithmException, CertificateException {
    -
    -		int certCount = 0;
    -
    -		KeyStore store = KeyStore.getInstance(KeyStore.getDefaultType());
    -		store.load(null);
    -
    -		InputStream fis = new FileInputStream(cacertsPath);
    -		BufferedInputStream bis = new BufferedInputStream(fis);
    -
    -		try {
    -			CertificateFactory cf = CertificateFactory.getInstance("X.509");
    -			while (bis.available() > 0) {
    -				try {
    -					Certificate cert = cf.generateCertificate(bis);
    -					if (cert instanceof X509Certificate) {
    -						X509Certificate x509Cert = (X509Certificate) cert;
    -						String name = getCommonName(x509Cert.getSubjectDN());
    -						store.setCertificateEntry(name, cert);
    -						++certCount;
    -					}
    -				}
    -				catch (CertificateException e) {
    -					// Must handle blank lines at bottom of file
    -					Throwable cause = e.getCause();
    -					if (cause != null && "Empty input".equals(cause.getMessage())) {
    -						break; // end of file
    -					}
    -					throw e;
    -				}
    -			}
    -		}
    -		finally {
    -			bis.close();
    -		}
    -		if (certCount == 0) {
    -			// Processing JKS files above produce "Empty input", if no certs read
    -			// try reading as keystore without password 
    -			return getKeyStoreInstance(cacertsPath, null);
    -		}
    -		return store;
    -	}
    -
    -	/**
    -	 * Attempt to load a client/server keystore in a PKCS12 form (*.p12, *.pks, *.pfx) or 
    -	 * Java JKS (*.jks) form.
    -	 * @param pwd keystore password
    -	 * @return keystore instance
    -	 * @throws IOException
    -	 * @throws KeyStoreException
    -	 * @throws NoSuchAlgorithmException
    -	 * @throws CertificateException
    -	 */
    -	public static KeyStore getKeyStoreInstance(String keystorePath, char[] pwd)
    -			throws IOException, KeyStoreException, NoSuchAlgorithmException, CertificateException {
    -
    -		File keystoreFile = new File(keystorePath);
    -		boolean isPKCS12 = ApplicationKeyManagerUtils.PKCS_FILENAME_FILTER.accept(keystoreFile);
    -		String type = isPKCS12 ? "PKCS12" : "JKS"; // JKS assumed if not PKCS
    -		KeyStore ks = KeyStore.getInstance(type);
    -
    -		InputStream fis = new FileInputStream(keystorePath);
    -		BufferedInputStream bis = new BufferedInputStream(fis);
    -		try {
    -			ks.load(bis, pwd);
    -		}
    -		finally {
    -			bis.close();
    -		}
    -		return ks;
    -	}
    -
    -	/**
    -	 * Attempt to detect PKI KeyStore type ("JKS" or "PKCS12") for the specified file.
    -	 * @param keystorePath key store file path
    -	 * @return "JKS", "PKCS12" or null
    -	 * @throws IOException if file read error occurs
    -	 */
    -	public static String detectKeyStoreType(String keystorePath) throws IOException {
    -		try (FileInputStream fis = new FileInputStream(keystorePath)) {
    -			byte[] header = new byte[4];
    -			int read = fis.read(header);
    -			if (read < 4) {
    -				return null;
    -			}
    -
    -			// Check for JKS magic number: FEEDFEED
    -			if ((header[0] & 0xFF) == 0xFE && (header[1] & 0xFF) == 0xED &&
    -				(header[2] & 0xFF) == 0xFE && (header[3] & 0xFF) == 0xED) {
    -				return "JKS";
    -			}
    -
    -			// Check for PKCS12: starts with 0x30 0x82
    -			if ((header[0] & 0xFF) == 0x30 && (header[1] & 0xFF) == 0x82) {
    -				return "PKCS12";
    -			}
    -
    -			return null;
    -		}
    -	}
    -
    -	/**
    -	 * Extract Common Name (CN) from specified principal subject Distinguished Name (DN)
    -	 * @param subject X.509 certificate subject
    -	 * @return Common Name or full subject name if unable to extract CN from DN
    -	 */
    -	private static String getCommonName(Principal subject) {
    -
    -		// Subject name should be distinguished-name (DN) which starts with common-name (CN)
    -		String name = subject.getName();
    -		int commaIndex = name.indexOf(',');
    -		String firstElement = commaIndex < 0 ? name : name.substring(0, commaIndex);
    -
    -		int equalsIndex = firstElement.indexOf('=');
    -		if (equalsIndex <= 0) {
    -			return name; // bad common name
    -		}
    -
    -		String fieldName = firstElement.substring(0, equalsIndex).trim();
    -		String fieldValue = firstElement.substring(equalsIndex + 1).trim();
    -
    -		if (!fieldName.equalsIgnoreCase("CN")) {
    -			return name; // bad common name
    -		}
    -
    -		return fieldValue;
    -	}
    -
    -	/**
    -	 * Log all X509 certificates contained within keystore
    -	 * @param keyStore certificate keystore
    -	 */
    -	static void logCerts(KeyStore keyStore) {
    -		try {
    -			Enumeration<String> aliases = keyStore.aliases();
    -			while (aliases.hasMoreElements()) {
    -				String alias = aliases.nextElement();
    -				Certificate certificate = keyStore.getCertificate(alias);
    -				if (certificate == null) {
    -					continue;
    -				}
    -				else if (certificate instanceof X509Certificate) {
    -					logCert(alias, (X509Certificate) certificate);
    -				}
    -				else {
    -					Msg.warn(ApplicationKeyStore.class, "Ignore unrecognized certificate: alias=" +
    -						alias + ", type=" + certificate.getType());
    -				}
    -			}
    -		}
    -		catch (KeyStoreException e) {
    -			Msg.error(ApplicationKeyStore.class, "KeyStore failure", e);
    -		}
    -	}
    -
    -	/**
    -	 * Log all X509 certificates contained within array
    -	 * @param x509Certs array of certificates
    -	 */
    -	public static void logCerts(X509Certificate[] x509Certs) {
    -		for (X509Certificate x509Cert : x509Certs) {
    -			logCert(null, x509Cert);
    -		}
    -	}
    -
    -	/**
    -	 * Log specified X509 certificate details
    -	 * @param alias certificate alias or null if not applicable
    -	 * @param x509Cert X509 certificate
    -	 */
    -	static void logCert(String alias, X509Certificate x509Cert) {
    -
    -		X500Principal subj = x509Cert.getSubjectX500Principal();
    -		X500Principal issuer = x509Cert.getIssuerX500Principal();
    -
    -		Date now = new Date();
    -
    -		String label = alias != null ? (alias + ": ") : "";
    -		if (now.compareTo(x509Cert.getNotAfter()) > 0) {
    -			Msg.warn(ApplicationKeyStore.class,
    -				"   " + label + getCommonName(subj) + ", issued by " + getCommonName(issuer) +
    -					", S/N " + x509Cert.getSerialNumber().toString(16) + ", expired " +
    -					x509Cert.getNotAfter() + " **EXPIRED**");
    -		}
    -		else {
    -			Msg.info(ApplicationKeyStore.class,
    -				"   " + label + getCommonName(subj) + ", issued by " + getCommonName(issuer) +
    -					", S/N " + x509Cert.getSerialNumber().toString(16) + ", expires " +
    -					x509Cert.getNotAfter());
    -		}
    -	}
    -
    -}
    
  • Ghidra/Framework/Generic/src/main/java/ghidra/net/ApplicationSSLSocketFactory.java+0 92 removed
    @@ -1,92 +0,0 @@
    -/* ###
    - * IP: GHIDRA
    - *
    - * Licensed under the Apache License, Version 2.0 (the "License");
    - * you may not use this file except in compliance with the License.
    - * You may obtain a copy of the License at
    - * 
    - *      http://www.apache.org/licenses/LICENSE-2.0
    - * 
    - * Unless required by applicable law or agreed to in writing, software
    - * distributed under the License is distributed on an "AS IS" BASIS,
    - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    - * See the License for the specific language governing permissions and
    - * limitations under the License.
    - */
    -package ghidra.net;
    -
    -import java.io.IOException;
    -import java.net.*;
    -import java.security.NoSuchAlgorithmException;
    -
    -import javax.net.ssl.SSLContext;
    -import javax.net.ssl.SSLSocketFactory;
    -
    -import ghidra.util.Msg;
    -
    -/**
    - * <code>ApplicationSSLSocketFactory</code> provides a replacement for the default
    - * <code>SSLSocketFactory</code> which utilizes the default SSLContext established
    - * by {@link SSLContextInitializer}.
    - */
    -public class ApplicationSSLSocketFactory extends SSLSocketFactory {
    -
    -	private final SSLSocketFactory socketFactory;
    -
    -	/**
    -	 * ApplicationSSLSocketFactory constructor.  
    -	 * SSLContext initialization will be performed using {@link SSLContextInitializer}.
    -	 */
    -	public ApplicationSSLSocketFactory() {
    -		SSLSocketFactory factory = null;
    -		try {
    -			if (SSLContextInitializer.initialize()) {
    -				factory = SSLContext.getDefault().getSocketFactory();
    -			}
    -		}
    -		catch (NoSuchAlgorithmException e) {
    -			Msg.error(this, "Failed to employ default SSLContext: " + e.toString(), e);
    -		}
    -		this.socketFactory =
    -			factory != null ? factory : (SSLSocketFactory) SSLSocketFactory.getDefault();
    -	}
    -
    -	@Override
    -	public Socket createSocket(Socket s, String host, int port, boolean autoClose)
    -			throws IOException {
    -		return socketFactory.createSocket(s, host, port, autoClose);
    -	}
    -
    -	@Override
    -	public String[] getDefaultCipherSuites() {
    -		return socketFactory.getDefaultCipherSuites();
    -	}
    -
    -	@Override
    -	public String[] getSupportedCipherSuites() {
    -		return socketFactory.getSupportedCipherSuites();
    -	}
    -
    -	@Override
    -	public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
    -		return socketFactory.createSocket(host, port);
    -	}
    -
    -	@Override
    -	public Socket createSocket(InetAddress host, int port) throws IOException {
    -		return socketFactory.createSocket(host, port);
    -	}
    -
    -	@Override
    -	public Socket createSocket(String host, int port, InetAddress localHost, int localPort)
    -			throws IOException, UnknownHostException {
    -		return socketFactory.createSocket(host, port, localHost, localPort);
    -	}
    -
    -	@Override
    -	public Socket createSocket(InetAddress address, int port, InetAddress localAddress,
    -			int localPort)
    -			throws IOException {
    -		return socketFactory.createSocket(address, port, localAddress, localPort);
    -	}
    -}
    
  • Ghidra/Framework/Generic/src/main/java/ghidra/net/DefaultKeyManagerFactory.java+512 0 added
    @@ -0,0 +1,512 @@
    +/* ###
    + * IP: GHIDRA
    + *
    + * Licensed under the Apache License, Version 2.0 (the "License");
    + * you may not use this file except in compliance with the License.
    + * You may obtain a copy of the License at
    + *
    + *      http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +package ghidra.net;
    +
    +import java.net.Socket;
    +import java.security.*;
    +import java.security.cert.CertificateException;
    +import java.security.cert.X509Certificate;
    +import java.util.*;
    +
    +import javax.net.ssl.*;
    +import javax.rmi.ssl.SslRMIClientSocketFactory;
    +import javax.security.auth.DestroyFailedException;
    +import javax.security.auth.x500.X500Principal;
    +
    +import org.apache.commons.lang3.StringUtils;
    +
    +import ghidra.framework.preferences.Preferences;
    +import ghidra.util.Msg;
    +import ghidra.util.SystemUtilities;
    +import ghidra.util.exception.CancelledException;
    +
    +/**
    + * {@link DefaultKeyManagerFactory} provides access to the default application key manager
    + * associated with the preferred keystore file specified by the {@link #KEYSTORE_PATH_PROPERTY}
    + * system property or set with {@link #setDefaultKeyStore(String, boolean)}.  
    + * <p>
    + * <p>
    + * NOTE: Since {@link SslRMIClientSocketFactory} and {@link SSLServerSocketFactory} employ a
    + * static cache of a default {@link SSLSocketFactory}, with its default {@link SSLContext}, we
    + * must utilize a wrapped implementation of the associated {@link X509ExtendedKeyManager} so that 
    + * an updated keystore is used by the existing default {@link SSLSocketFactory}.
    + */
    +public class DefaultKeyManagerFactory {
    +
    +	/**
    +	 * Keystore path system property or user preference.  Setting the system
    +	 * property will take precedence over the user preference.
    +	 */
    +	public static final String KEYSTORE_PATH_PROPERTY = "ghidra.keystore";
    +
    +	/**
    +	 * Password system property may be set.  If set, this password will be used
    +	 * when accessing the keystore before attempting to use <code>customPasswordProvider</code>
    +	 * if it has been set.
    +	 */
    +	public static final String KEYSTORE_PASSWORD_PROPERTY = "ghidra.password";
    +
    +	public static final String DEFAULT_PASSWORD = "changeme";
    +
    +	private static final int SELF_SIGNED_DURATION_DAYS = 2 * 365; // 2-years
    +
    +	// Certificate info when self-signed cert is used
    +	private static X500Principal defaultIdentity;
    +	private static List<String> defaultSubjectAlternativeNames;
    +
    +	// Factory maintains a single X509 key manager
    +	private static final DefaultX509KeyManager keyManagerWrapper = new DefaultX509KeyManager();
    +
    +	/**
    +	 * Prune path to trim leading and trailing white space. A null will be
    +	 * returned if the pruned path is null or the empty string.
    +	 *
    +	 * @param path file path to be pruned (may be null)
    +	 * @return pruned path or null if path was null or pruned path was the empty
    +	 *         string
    +	 */
    +	private static String prunePath(String path) {
    +		if (path != null) {
    +			path = path.trim();
    +			if (path.length() == 0) {
    +				path = null;
    +			}
    +		}
    +		return path;
    +	}
    +
    +	/**
    +	 * Set default user keystore file path (e.g., certificate file with private key).
    +	 * This method will have no effect if the keystore had been set via the system
    +	 * property and an error will be displayed.  Otherwise, the keystore will
    +	 * be updated and the key manager re-initialized.  The user preference will be
    +	 * updated unless a failure occurred while attempting to open the keystore.
    +	 * This change will take immediate effect for the current executing application,
    +	 * however, it may still be superseded by a system property setting when running
    +	 * the application in the future. See {@link #getKeyStore()}.
    +	 * 
    +	 * @param path keystore file path or null to clear current key store and preference.
    +	 * @param savePreference if true will be saved as user preference
    +	 * @return true if successful else false if error occured (see log).
    +	 */
    +	public static synchronized boolean setDefaultKeyStore(String path, boolean savePreference) {
    +
    +		if (System.getProperty(KEYSTORE_PATH_PROPERTY) != null) {
    +			Msg.showError(DefaultKeyManagerFactory.class, null, "Set KeyStore Failed",
    +				"PKI KeyStore was set via system property and can not be changed");
    +			return false;
    +		}
    +
    +		path = prunePath(path);
    +
    +		try {
    +			boolean keyInitialized = keyManagerWrapper.init(path);
    +
    +			if (savePreference && (path == null || keyInitialized)) {
    +				Preferences.setProperty(KEYSTORE_PATH_PROPERTY, path);
    +				Preferences.store();
    +			}
    +			return keyInitialized;
    +		}
    +		catch (CancelledException e) {
    +			// ignore - keystore left unchanged
    +			return false;
    +		}
    +	}
    +
    +	/**
    +	 * Determine if active key manager is utilizing a generated self-signed certificate.
    +	 * 
    +	 * @return true if using self-signed certificate.
    +	 */
    +	public static synchronized boolean usingGeneratedSelfSignedCertificate() {
    +		return keyManagerWrapper.usingGeneratedSelfSignedCertificate();
    +	}
    +
    +	/**
    +	 * Set the default self-signed principal identity to be used during initialization
    +	 * if no keystore defined.  Current application key manager will be invalidated.
    +	 * (NOTE: this is intended for server use only when client will not be performing
    +	 * CA validation).
    +	 * 
    +	 * @param identity if not null and a KeyStore path has not be set, this
    +	 * identity will be used to generate a self-signed certificate and private key
    +	 */
    +	public synchronized static void setDefaultIdentity(X500Principal identity) {
    +		defaultIdentity = identity;
    +		keyManagerWrapper.invalidateKey();
    +	}
    +
    +	/**
    +	 * Add the optional self-signed subject alternative name to be used during initialization
    +	 * if no keystore defined.  Current application key manager will be invalidated.
    +	 * (NOTE: this is intended for server use only when client will not be performing
    +	 * CA validation).
    +	 * @param subjectAltName name to be added to the current list of alternative subject names.
    +	 * A null value will clear all names currently set.  
    +	 * name will be used to generate a self-signed certificate and private key
    +	 */
    +	public synchronized static void addSubjectAlternativeName(String subjectAltName) {
    +		if (subjectAltName == null) {
    +			defaultSubjectAlternativeNames = null;
    +		}
    +		else {
    +			if (defaultSubjectAlternativeNames == null) {
    +				defaultSubjectAlternativeNames = new ArrayList<>();
    +			}
    +			defaultSubjectAlternativeNames.add(subjectAltName);
    +		}
    +		keyManagerWrapper.invalidateKey();
    +	}
    +
    +	/**
    +	 * Initialize key manager if needed.  Doing this explicitly independent of an SSL connection
    +	 * allows application to bail before initiating connection.  This will get handshake failure
    +	 * if user forgets keystore password or other keystore problem.
    +	 * @return true if key manager initialized, otherwise false
    +	 */
    +	public synchronized static boolean initialize() {
    +		try {
    +			return keyManagerWrapper.init();
    +		}
    +		catch (CancelledException e) {
    +			return false;
    +		}
    +	}
    +
    +	/**
    +	 * Invalidate the existing default key manager.
    +	 */
    +	public synchronized static void invalidateKeyManager() {
    +		keyManagerWrapper.invalidateKey();
    +	}
    +
    +	/**
    +	 * If the system property <i>ghidra.keystore</i> takes precedence in establishing 
    +	 * the keystore.  If using a GUI and the system property has not been set, the 
    +	 * user preference with the same name will be used.
    +	 * @return active keystore path or null if currently not running with a keystore or
    +	 * one has not been set.
    +	 */
    +	public static synchronized String getPreferredKeyStore() {
    +		String path = prunePath(System.getProperty(KEYSTORE_PATH_PROPERTY));
    +		if (path == null && !SystemUtilities.isInHeadlessMode()) {
    +			path = prunePath(Preferences.getProperty(KEYSTORE_PATH_PROPERTY));
    +		}
    +		return path;
    +	}
    +
    +	/**
    +	 * Get the default/preferred key store path.
    +	 * @return default key store path or null if not set
    +	 */
    +	public static synchronized String getKeyStore() {
    +		return keyManagerWrapper.getKeyStore();
    +	}
    +
    +	/**
    +	 * Get the lazy default key manager associated with the preferred key store.
    +	 * @return default key manager or null if not initialized
    +	 */
    +	public static synchronized X509ExtendedKeyManager getKeyManager() {
    +		return keyManagerWrapper;
    +	}
    +
    +	/**
    +	 * <code>DefaultKeyManager</code> provides a wrapper for the X509 wrappedKeyManager whose
    +	 * instantiation is delayed until needed.  When a wrapper method is first invoked, the
    +	 * {@link DefaultX509KeyManager#init()} method is called to open the keystore
    +	 * (which may require a password prompt) and establish the underlying X509KeyManager.
    +	 */
    +	private static class DefaultX509KeyManager extends X509ExtendedKeyManager {
    +
    +		private X509KeyManager wrappedKeyManager;
    +		private String keystorePath;
    +		private boolean isSelfSigned = false;
    +
    +		@Override
    +		public String chooseEngineServerAlias(String keyType, Principal[] issuers,
    +				SSLEngine engine) {
    +			return super.chooseEngineServerAlias(keyType, issuers, engine);
    +		}
    +
    +		@Override
    +		public String chooseEngineClientAlias(String[] keyType, Principal[] issuers,
    +				SSLEngine engine) {
    +			return super.chooseEngineClientAlias(keyType, issuers, engine);
    +		}
    +
    +		@Override
    +		public synchronized String chooseClientAlias(String[] keyType, Principal[] issuers,
    +				Socket socket) {
    +			try {
    +				init();
    +			}
    +			catch (CancelledException e) {
    +				// ignore
    +			}
    +			if (wrappedKeyManager == null) {
    +				return null;
    +			}
    +			return wrappedKeyManager.chooseClientAlias(keyType, issuers, socket);
    +		}
    +
    +		@Override
    +		public synchronized String chooseServerAlias(String keyType, Principal[] issuers,
    +				Socket socket) {
    +			try {
    +				init();
    +			}
    +			catch (CancelledException e) {
    +				// ignore
    +			}
    +			if (wrappedKeyManager == null) {
    +				return null;
    +			}
    +			return wrappedKeyManager.chooseServerAlias(keyType, issuers, socket);
    +		}
    +
    +		@Override
    +		public String[] getClientAliases(String keyType, Principal[] issuers) {
    +			try {
    +				init();
    +			}
    +			catch (CancelledException e) {
    +				// ignore
    +			}
    +			if (wrappedKeyManager == null) {
    +				return null;
    +			}
    +			return wrappedKeyManager.getClientAliases(keyType, issuers);
    +		}
    +
    +		@Override
    +		public String[] getServerAliases(String keyType, Principal[] issuers) {
    +			try {
    +				init();
    +			}
    +			catch (CancelledException e) {
    +				// ignore
    +			}
    +			if (wrappedKeyManager == null) {
    +				return null;
    +			}
    +			return wrappedKeyManager.getServerAliases(keyType, issuers);
    +		}
    +
    +		@Override
    +		public X509Certificate[] getCertificateChain(String alias) {
    +			if (wrappedKeyManager == null) {
    +				return null;
    +			}
    +			return wrappedKeyManager.getCertificateChain(alias);
    +		}
    +
    +		@Override
    +		public PrivateKey getPrivateKey(String alias) {
    +			if (wrappedKeyManager == null) {
    +				return null;
    +			}
    +			return wrappedKeyManager.getPrivateKey(alias);
    +		}
    +
    +		/**
    +		 * Invalidate the active keystore and key manager
    +		 */
    +		private synchronized void invalidateKey() {
    +			wrappedKeyManager = null;
    +			keystorePath = null;
    +			isSelfSigned = false;
    +		}
    +
    +		/**
    +		 * Return active keystore path or preferred keystore path if not yet initialized.
    +		 * @return active keystore path or preferred keystore path if not yet initialized.
    +		 */
    +		private synchronized String getKeyStore() {
    +			return keystorePath != null ? keystorePath : getPreferredKeyStore();
    +		}
    +
    +		/**
    +		 * Determine if active key manager is utilizing a generated self-signed certificate.
    +		 * @return true if using self-signed certificate.
    +		 */
    +		private synchronized boolean usingGeneratedSelfSignedCertificate() {
    +			return wrappedKeyManager != null && isSelfSigned;
    +		}
    +
    +		/**
    +		 * Initialize the default x509KeyManager singleton wrappedKeyManager associated with the 
    +		 * preferred keystore path.
    +		 * If the <code>x509KeyManager</code> already exists, this method has no affect.  If the
    +		 * <code>keystorePath</code> has not already been set, the <code>getPreferredKeyStore()</code>
    +		 * method will be invoked to obtain the keystore which should be used in establishing the
    +		 * <code>wrappedKeyManager</code>.  If no keystore has been identified and the Default Identity
    +		 * has been set, a self-signed certificate will be generated.  If nothing has been set, the
    +		 * wrappedKeyManager will remain null and false will be returned.  If an error occurs it
    +		 * will be logged and key managers will remain uninitialized.
    +		 * @return true if key manager initialized successfully or was previously initialized, else
    +		 * false if keystore path has not been set and default identity for self-signed certificate
    +		 * has not be established (see {@link DefaultKeyManagerFactory#setDefaultIdentity(X500Principal)}).
    +		 * @throws CancelledException user cancelled keystore password entry request
    +		 */
    +		private synchronized boolean init() throws CancelledException {
    +			if (wrappedKeyManager != null) {
    +				return true;
    +			}
    +			return init(getPreferredKeyStore());
    +		}
    +
    +		/**
    +		 * Initialize the default x509KeyManager singleton wrappedKeyManager using the specified path.
    +		 * If the <code>x509KeyManager</code> already exists for the specified keystore path,
    +		 * this method has no affect.  If no keystore has been identified and the Default Identity
    +		 * has been set, a self-signed certificate will be generated.  If nothing has been set, the
    +		 * wrappedKeyManager will remain null and false will be returned.  If an error occurs it
    +		 * will be logged and key managers will remain uninitialized.
    +		 * @param newKeystorePath specifies the keystore to be opened or null for no keystore
    +		 * @return true if key manager initialized successfully or was previously initialized, else
    +		 * false if new keystore path was not specified and default identity for self-signed certificate
    +		 * has not be established (see {@link DefaultKeyManagerFactory#setDefaultIdentity(X500Principal)}).
    +		 * @throws CancelledException user cancelled keystore password entry request
    +		 */
    +		private synchronized boolean init(String newKeystorePath) throws CancelledException {
    +
    +			if (wrappedKeyManager != null) {
    +				if (StringUtils.equals(keystorePath, newKeystorePath)) {
    +					return true;
    +				}
    +				invalidateKey();
    +			}
    +
    +			isSelfSigned = false;
    +			try {
    +				if (newKeystorePath != null && newKeystorePath.length() != 0) {
    +					Msg.info(DefaultKeyManagerFactory.class,
    +						"Using certificate keystore: " + newKeystorePath);
    +					// Password optionally specified via property
    +					String keystorePwd = System.getProperty(KEYSTORE_PASSWORD_PROPERTY);
    +					wrappedKeyManager =
    +						ApplicationKeyManagerFactory.getKeyManager(newKeystorePath, keystorePwd);
    +					keystorePath = newKeystorePath; // update current keystore path
    +				}
    +				else if (defaultIdentity != null) {
    +					// use self-signed keystore as fallback (intended for server use only)
    +					Msg.info(this, "Using self-signed certificate: " + defaultIdentity.getName());
    +					char[] pwd = DEFAULT_PASSWORD.toCharArray();
    +					KeyStore selfSignedKeyStore = PKIUtils.createKeyStore("defaultSigKey",
    +						defaultIdentity.getName(), SELF_SIGNED_DURATION_DAYS, null, null, "JKS",
    +						defaultSubjectAlternativeNames, pwd);
    +					wrappedKeyManager = ApplicationKeyManagerFactory
    +							.getKeyManagerFromKeyStore(selfSignedKeyStore, pwd);
    +					isSelfSigned = true;
    +				}
    +				else {
    +					return false;
    +				}
    +				return true;
    +			}
    +			catch (CancelledException e) {
    +				throw e;
    +			}
    +			catch (Exception e) {
    +				Msg.showError(this, null, "PKI Keystore Failure",
    +					"Failed to create PKI key manager: " + e.getMessage(), e);
    +			}
    +			return false;
    +		}
    +	}
    +
    +	/**
    +	 * Sign the supplied token byte array using an installed certificate from
    +	 * one of the specified authorities
    +	 * @param authorities trusted certificate authorities used to constrain client certificate
    +	 *   (may be null or empty array if CA constraint does not matter).
    +	 * @param token token byte array
    +	 * @return signed token object
    +	 * @throws NoSuchAlgorithmException algorithm associated within signing certificate not found
    +	 * @throws SignatureException failed to generate SignedToken
    +	 * @throws CertificateException error associated with signing certificate
    +	 */
    +	public static SignedToken getSignedToken(Principal[] authorities, byte[] token)
    +			throws NoSuchAlgorithmException, SignatureException, CertificateException {
    +
    +		PrivateKey privateKey = null;
    +		X509Certificate[] certificateChain = null;
    +		try {
    +			X509ExtendedKeyManager x509KeyManager = getKeyManager();
    +			if (x509KeyManager != null) {
    +				String alias = x509KeyManager.chooseClientAlias(new String[] { PKIUtils.RSA_TYPE },
    +					authorities, null);
    +				if (alias != null) {
    +					privateKey = x509KeyManager.getPrivateKey(alias);
    +					certificateChain = x509KeyManager.getCertificateChain(alias);
    +				}
    +			}
    +			if (privateKey == null || certificateChain == null) {
    +				CertificateException e =
    +					new CertificateException("suitable PKI certificate not found");
    +				e.printStackTrace();
    +				throw e;
    +			}
    +
    +			//
    +			// See JAVA Examples in a Nutshell (p.358) for use of Signer and
    +			// IdentityScope classes
    +			//
    +
    +			String algorithm = certificateChain[0].getSigAlgName();
    +			Signature sig = Signature.getInstance(algorithm);
    +			try {
    +				sig.initSign(privateKey);
    +			}
    +			catch (InvalidKeyException e) {
    +				throw new CertificateException("suitable PKI certificate not found", e);
    +			}
    +			sig.update(token);
    +
    +			return new SignedToken(token, sig.sign(), certificateChain, algorithm);
    +		}
    +		finally {
    +			if (privateKey != null) {
    +				// Note: Keystore destroy only supported in Java 1.8
    +				try {
    +					privateKey.destroy();
    +				}
    +				catch (DestroyFailedException e) {
    +					// ignore - may not be supported by all keystores
    +				}
    +			}
    +		}
    +	}
    +
    +	/**
    +	 * Verify that the specified sigBytes reflect my signature of the specified token.
    +	 * @param authorities trusted certificate authorities used to constrain client certificate
    +	 *   (may be null or empty array if CA constraint does not matter).
    +	 * @param token byte array token
    +	 * @param signature token signature
    +	 * @return true if signature is my signature
    +	 * @throws NoSuchAlgorithmException algorithym associated within signing certificate not found
    +	 * @throws SignatureException failed to generate SignedToken
    +	 * @throws CertificateException error associated with signing certificate
    +	 */
    +	public static boolean isMySignature(Principal[] authorities, byte[] token, byte[] signature)
    +			throws NoSuchAlgorithmException, SignatureException, CertificateException {
    +		SignedToken signedToken = getSignedToken(authorities, token);
    +		return Arrays.equals(signature, signedToken.signature);
    +	}
    +}
    
  • Ghidra/Framework/Generic/src/main/java/ghidra/net/DefaultSSLContextInitializer.java+22 16 renamed
    @@ -4,9 +4,9 @@
      * Licensed under the Apache License, Version 2.0 (the "License");
      * you may not use this file except in compliance with the License.
      * You may obtain a copy of the License at
    - * 
    + *
      *      http://www.apache.org/licenses/LICENSE-2.0
    - * 
    + *
      * Unless required by applicable law or agreed to in writing, software
      * distributed under the License is distributed on an "AS IS" BASIS,
      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    @@ -26,21 +26,17 @@
     /**
      * Initialize the default SSLContext for use by all SSL connections (e.g., https).
      * It is the responsibility of the Application to properly invoke this initializer 
    - * to ensure that the default SSLContext is properly established. While HTTPS URL connections
    - * will make use of this default SSLContext, other SSL connections may need to 
    - * specify the {@link ApplicationSSLSocketFactory} to leverage the applications
    - * default SSLContext.
    + * to ensure that the default SSLContext is properly established.
      * <p>
      * The property <code>jdk.tls.client.protocols</code> should be set to restrict secure
      * client connections to a specific set of enabled TLS protocols (e.g., TLSv1.2,TLSv1.3).
      * See <A href="https://java.com/en/configure_crypto.html">JDK and JRE Cryptographic Algorithms</A> 
      * for details.
      * 
    - * @see ApplicationTrustManagerFactory
    - * @see ApplicationKeyManagerFactory
    - * @see ApplicationKeyManagerUtils
    + * @see DefaultTrustManagerFactory
    + * @see DefaultKeyManagerFactory
      */
    -public class SSLContextInitializer implements ModuleInitializer {
    +public class DefaultSSLContextInitializer implements ModuleInitializer {
     
     	private static final String DEFAULT_SSL_PROTOCOL = "TLS";
     
    @@ -56,8 +52,8 @@ public class SSLContextInitializer implements ModuleInitializer {
     	public static synchronized boolean initialize(boolean reset) {
     		if (reset) {
     			sslContext = null;
    -			ApplicationTrustManagerFactory.invalidateTrustManagers();
    -			ApplicationKeyManagerFactory.invalidateKeyManagers();
    +			DefaultTrustManagerFactory.invalidateTrustManagers();
    +			DefaultKeyManagerFactory.invalidateKeyManager();
     		}
     		return initialize();
     	}
    @@ -73,15 +69,25 @@ public static synchronized boolean initialize() {
     			return true;
     		}
     
    -		Msg.info(SSLContextInitializer.class, "Initializing SSL Context");
    +		Msg.info(DefaultSSLContextInitializer.class, "Initializing SSL Context");
     
    -		KeyManager[] keyManagers = ApplicationKeyManagerFactory.getInstance().getKeyManagers();
    +		KeyManager keyManager = DefaultKeyManagerFactory.getKeyManager();
     
     		try {
     			// Use new instance of SSLContext to avoid adopting CA certs provided with Java
     			sslContext = SSLContext.getInstance(DEFAULT_SSL_PROTOCOL);
     			SecureRandom random = SecureRandomFactory.getSecureRandom();
    -			sslContext.init(keyManagers, ApplicationTrustManagerFactory.getTrustManagers(), random);
    +			sslContext.init(new KeyManager[] { keyManager },
    +				DefaultTrustManagerFactory.getTrustManagers(), random);
    +
    +			//
    +			// NOTE: The SslRMIClientSocketFactory and SslRMIServerSocketFactory both statically 
    +			// cache their 'defaultSocketFactory' which prevents it from utilizing a new
    +			// default SSLContext.  This requires us to employ a wrapped TrustManager and
    +			// wrapped KeyManager to allow for them to possibly be revised after first use
    +			// (e.g., JUnit testing, new user PKI Certificate, etc.).
    +			//
    +
     			SSLContext.setDefault(sslContext);
     
     			// Must install default HostnameVerifier - otherwise all traffic will fail
    @@ -101,7 +107,7 @@ public static synchronized boolean initialize() {
     
     		}
     		catch (Exception e) {
    -			Msg.error(SSLContextInitializer.class,
    +			Msg.error(DefaultSSLContextInitializer.class,
     				"SSL Context initialization failed: " + e.getMessage(), e);
     		}
     		return false;
    
  • Ghidra/Framework/Generic/src/main/java/ghidra/net/DefaultTrustManagerFactory.java+115 77 renamed
    @@ -20,16 +20,20 @@
     import java.security.KeyStore;
     import java.security.cert.CertificateException;
     import java.security.cert.X509Certificate;
    +import java.util.HashSet;
    +import java.util.Set;
     
     import javax.net.ssl.*;
    +import javax.rmi.ssl.SslRMIClientSocketFactory;
    +import javax.security.auth.x500.X500Principal;
     
     import ghidra.framework.preferences.Preferences;
     import ghidra.util.Msg;
     
     /**
    - * <code>ApplicationTrustManagerFactory</code> provides the ability to establish
    - * acceptable certificate authorities to be used with SSL connections and PKI 
    - * authentication.  
    + * <code>DefaultTrustManagerFactory</code> provides the ability to establish
    + * acceptable certificate authorities to be used with the default SSLContext
    + * as established by {@link DefaultSSLContextInitializer}. 
      * <p>
      * The default behavior is for no trust authority to be established, in which case 
      * SSL peers will not be authenticated.  If CA certificates have been set, all SSL
    @@ -47,8 +51,13 @@
      * <p>
      * The application may choose to set the file path automatically based upon the presence of
      * a <i>cacerts</i> file at a predetermined location.
    + * <p>
    + * NOTE: Since {@link SslRMIClientSocketFactory} and {@link SSLServerSocketFactory} employ a
    + * static cache of a default {@link SSLSocketFactory}, with its default {@link SSLContext}, we
    + * must utilize a wrapped implementation of the associated {@link X509TrustManager} so that any
    + * changes are used by the existing default {@link SSLSocketFactory}.
      */
    -public class ApplicationTrustManagerFactory {
    +public class DefaultTrustManagerFactory {
     
     	/**
     	 * The X509 cacerts file to be used when authenticating remote 
    @@ -57,22 +66,20 @@ public class ApplicationTrustManagerFactory {
     	 */
     	public static final String GHIDRA_CACERTS_PATH_PROPERTY = "ghidra.cacerts";
     
    +	private static final X509Certificate[] NO_CERTS = new X509Certificate[0];
    +
     	/**
     	 * Use a singleton wrappedTrustManager so we can alter the true trustManager
     	 * as needed.  Once the installed trust manager is consumed by the SSL Engine,
     	 * we are unable to get it to use a new one.  Use of a wrapper solves this
     	 * issue which occurs during testing.
     	 */
    -	private static X509TrustManager trustManager;
    -	private static TrustManager[] wrappedTrustManagers;
    -
    -	private static boolean hasCAs;
    -	private static Exception caError;
    +	private static final WrappedTrustManager wrappedTrustManager = new WrappedTrustManager();
     
     	/**
     	 * <code>ApplicationTrustManagerFactory</code> constructor
     	 */
    -	private ApplicationTrustManagerFactory() {
    +	private DefaultTrustManagerFactory() {
     		// no instantiation - static methods only
     	}
     
    @@ -83,138 +90,169 @@ private ApplicationTrustManagerFactory() {
     	 */
     	private static void init() {
     
    -		if (wrappedTrustManagers == null) {
    -			wrappedTrustManagers = new WrappedTrustManager[] { new WrappedTrustManager() };
    -		}
    -
     		String cacertsPath = System.getProperty(GHIDRA_CACERTS_PATH_PROPERTY);
     		if (cacertsPath == null || cacertsPath.length() == 0) {
     			// check user preferences if cacerts not set via system property
     			cacertsPath = Preferences.getProperty(GHIDRA_CACERTS_PATH_PROPERTY);
     			if (cacertsPath == null || cacertsPath.length() == 0) {
    -				Msg.info(ApplicationTrustManagerFactory.class,
    +				Msg.info(DefaultTrustManagerFactory.class,
     					"Trust manager disabled, cacerts have not been set");
    -				trustManager = new OpenTrustManager();
    +				wrappedTrustManager.setTrustManager(new OpenTrustManager());
     				return;
     			}
     		}
     
     		try {
    -			Msg.info(ApplicationTrustManagerFactory.class,
    +			Msg.info(DefaultTrustManagerFactory.class,
     				"Trust manager initializing with cacerts: " + cacertsPath);
    -			KeyStore keyStore = ApplicationKeyStore.getCertificateStoreInstance(cacertsPath);
    +			KeyStore keyStore = PKIUtils.loadCertificateStore(cacertsPath);
     			TrustManagerFactory tmf =
     				TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
     			tmf.init(keyStore);
    +			X509TrustManager x509TrustMgr = null;
     			TrustManager[] trustManagers = tmf.getTrustManagers();
    -			for (TrustManager trustManager2 : trustManagers) {
    -				if (trustManager2 instanceof X509TrustManager) {
    -					X509TrustManager mgr = (X509TrustManager) trustManager2;
    -					ApplicationKeyStore.logCerts(mgr.getAcceptedIssuers());
    -					trustManager = mgr;
    +			for (TrustManager trustMgr : trustManagers) {
    +				if (trustMgr instanceof X509TrustManager) {
    +					x509TrustMgr = (X509TrustManager) trustMgr;
    +					wrappedTrustManager.setTrustManager(x509TrustMgr);
    +					PKIUtils.logCerts(x509TrustMgr.getAcceptedIssuers());
     					break;
     				}
     			}
    -			hasCAs = true;
    +			if (x509TrustMgr == null) {
    +				throw new CertificateException("Failed to load any X509 certificates");
    +			}
     		}
     		catch (GeneralSecurityException | IOException e) {
    -			caError = e;
    +			wrappedTrustManager.setTrustManagerError(e);
     			String msg = e.getMessage();
     			if (msg == null) {
     				msg = e.toString();
     			}
    -			Msg.error(ApplicationTrustManagerFactory.class,
    +			Msg.error(DefaultTrustManagerFactory.class,
     				"Failed to process cacerts (" + cacertsPath + "): " + msg, e);
     		}
     	}
     
     	/**
    -	 * Determine if certificate authorities are in place.  If no certificate authorities
    -	 * have been specified via the "ghidra.cacerts" property, all certificates will be 
    -	 * trusted. 
    -	 * @return true if certificate authorities are in place, else false.
    +	 * Get trust manager after performing any necessary initialization.
    +	 * 
    +	 * @return trust managers
     	 */
    -	public static boolean hasCertificateAuthorities() {
    -		return hasCAs;
    +	public static synchronized TrustManager[] getTrustManagers() {
    +		if (wrappedTrustManager.trustManager == null) {
    +			init();
    +		}
    +		return new TrustManager[] { wrappedTrustManager };
     	}
     
     	/**
    -	 * Determine if a CA cert initialization error occurred
    -	 * @return true if error occurred (see {@link #getCertError()})
    +	 * Invalidate the active keystore and key manager.
    +	 * 
    +	 * NOTE: This should only be invoked by {@link DefaultSSLContextInitializer}.
     	 */
    -	static boolean hasCertError() {
    -		return caError != null;
    +	static synchronized void invalidateTrustManagers() {
    +		wrappedTrustManager.invalidate();
     	}
     
     	/**
    -	 * Get the CA cert initialization error which occurred
    -	 * during initialization 
    -	 * @return error object or null if not applicable
    +	 * Returns a list of trusted issuers (i.e., CA certificates) as established
    +	 * by the {@link DefaultTrustManagerFactory}.
    +	 * 
    +	 * @return array of trusted Certificate Authorities
    +	 * @throws CertificateException if failed to properly initialize trust manager
    +	 * due to CA certificate error(s).
     	 */
    -	static Exception getCertError() {
    -		return caError;
    +	public static X500Principal[] getTrustedIssuers() throws CertificateException {
    +		return wrappedTrustManager.getTrustedIssuers();
     	}
     
     	/**
    -	 * Get trust managers after performing any necessary initialization.
    -	 * @return trust managers
    +	 * Validate a client certificate ensuring that it is not expired and is
    +	 * trusted based upon the active trust managers.
    +	 * @param certChain X509 certificate chain
    +	 * @param authType authentication type (i.e., "RSA")
    +	 * @throws CertificateException if certificate validation fails
     	 */
    -	static synchronized TrustManager[] getTrustManagers() {
    -		if (trustManager == null) {
    -			init();
    -		}
    -		return wrappedTrustManagers.clone();
    +	public static void validateClient(X509Certificate[] certChain, String authType)
    +			throws CertificateException {
    +		wrappedTrustManager.checkClientTrusted(certChain, authType);
     	}
    -	
    -	/**
    -     * Get trust manager after performing any necessary initialization.
    -     * @return trust managers
    -     */
    -    public static synchronized X509TrustManager getTrustManager() {
    -        if (trustManager == null) {
    -            init();
    -        }
    -        return trustManager;
    -    }
     
    -	/**
    -	 * Invalidate the active keystore and key manager 
    -	 */
    -	static synchronized void invalidateTrustManagers() {
    -		trustManager = null;
    -		caError = null;
    -	}
    +	private static class WrappedTrustManager implements X509TrustManager {
     
    -	private static final X509Certificate[] NO_CERTS = new X509Certificate[0];
    +		private X509TrustManager trustManager;
    +		private Exception caError;
     
    -	private static class WrappedTrustManager implements X509TrustManager {
    +		WrappedTrustManager() {
    +			invalidate();
    +		}
    +
    +		void invalidate() {
    +			this.trustManager = null;
    +			this.caError = null;
    +		}
    +
    +		synchronized void setTrustManager(X509TrustManager trustManager) {
    +			this.trustManager = trustManager;
    +			this.caError = null;
    +		}
    +
    +		synchronized void setTrustManagerError(Exception caError) {
    +			this.trustManager = null;
    +			this.caError = caError;
    +		}
     
     		@Override
    -		public void checkClientTrusted(X509Certificate[] chain, String authType)
    +		public synchronized void checkClientTrusted(X509Certificate[] chain, String authType)
     				throws CertificateException {
    -			if (trustManager == null) {
    -				throw new CertificateException("Trust manager not properly initialized");
    -			}
    +			checkTrustManager();
     			trustManager.checkClientTrusted(chain, authType);
     		}
     
     		@Override
    -		public void checkServerTrusted(X509Certificate[] chain, String authType)
    +		public synchronized void checkServerTrusted(X509Certificate[] chain, String authType)
     				throws CertificateException {
    -			if (trustManager == null) {
    -				throw new CertificateException("Trust manager not properly initialized");
    -			}
    +			checkTrustManager();
     			trustManager.checkServerTrusted(chain, authType);
     		}
     
     		@Override
    -		public X509Certificate[] getAcceptedIssuers() {
    +		public synchronized X509Certificate[] getAcceptedIssuers() {
     			if (trustManager == null) {
     				return NO_CERTS;
     			}
     			return trustManager.getAcceptedIssuers();
     		}
     
    +		synchronized X500Principal[] getTrustedIssuers() throws CertificateException {
    +
    +			WrappedTrustManager trustMgr = wrappedTrustManager;
    +			trustMgr.checkTrustManager();
    +
    +			X509Certificate[] acceptedIssuers = trustMgr.getAcceptedIssuers();
    +			if (acceptedIssuers == null || acceptedIssuers.length == 0) {
    +				return null; // trust all authorities
    +			}
    +
    +			Set<X500Principal> set = new HashSet<>();
    +			for (X509Certificate trustedCert : acceptedIssuers) {
    +				set.add(trustedCert.getSubjectX500Principal());
    +			}
    +			X500Principal[] principals = new X500Principal[set.size()];
    +			return set.toArray(principals);
    +		}
    +
    +		private void checkTrustManager() throws CertificateException {
    +			if (trustManager != null) {
    +				return;
    +			}
    +			if (caError != null) {
    +				throw new CertificateException("Failed to load CA certs", caError);
    +			}
    +			throw new CertificateException("Trust manager not properly initialized");
    +		}
    +
     	}
     
     	/**
    
  • Ghidra/Framework/Generic/src/main/java/ghidra/net/HttpClients.java+4 4 modified
    @@ -4,9 +4,9 @@
      * Licensed under the Apache License, Version 2.0 (the "License");
      * you may not use this file except in compliance with the License.
      * You may obtain a copy of the License at
    - * 
    + *
      *      http://www.apache.org/licenses/LICENSE-2.0
    - * 
    + *
      * Unless required by applicable law or agreed to in writing, software
      * distributed under the License is distributed on an "AS IS" BASIS,
      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    @@ -47,8 +47,8 @@ public class HttpClients {
     	 * @throws IOException if error in PKI settings or crypto configuration 
     	 */
     	public static HttpClient.Builder newHttpClientBuilder() throws IOException {
    -		if (!ApplicationKeyManagerFactory.initialize()) {
    -			if (ApplicationKeyManagerFactory.getKeyStore() != null) {
    +		if (!DefaultKeyManagerFactory.initialize()) {
    +			if (DefaultKeyManagerFactory.getKeyStore() != null) {
     				throw new IOException("Failed to initialize PKI certificate keystore");
     			}
     		}
    
  • Ghidra/Framework/Generic/src/main/java/ghidra/net/http/HttpUtil.java+7 8 modified
    @@ -4,9 +4,9 @@
      * Licensed under the Apache License, Version 2.0 (the "License");
      * you may not use this file except in compliance with the License.
      * You may obtain a copy of the License at
    - * 
    + *
      *      http://www.apache.org/licenses/LICENSE-2.0
    - * 
    + *
      * Unless required by applicable law or agreed to in writing, software
      * distributed under the License is distributed on an "AS IS" BASIS,
      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    @@ -19,12 +19,11 @@
     import java.net.*;
     import java.util.Properties;
     
    -import ghidra.net.ApplicationKeyManagerFactory;
    +import ghidra.net.DefaultKeyManagerFactory;
     import ghidra.util.Msg;
     
     public class HttpUtil {
     
    -
     	/**
     	 * Execute an HTTP/HTTPS GET request and return the resulting HttpURLConnection.
     	 * @param httpUrlString HTTP/HTTPS URL
    @@ -35,16 +34,16 @@ public class HttpUtil {
     	 * @throws IOException if an error occurs while executing request
     	 */
     	public static HttpURLConnection getContent(String httpUrlString,
    -			Properties httpRequestProperties, boolean allowRedirect) throws MalformedURLException,
    -			IOException {
    +			Properties httpRequestProperties, boolean allowRedirect)
    +			throws MalformedURLException, IOException {
     
     		URL url = new URL(httpUrlString);
     		String protocol = url.getProtocol();
     
     		if ("https".equals(protocol)) {
     			// force password prompt before connecting
    -			if (!ApplicationKeyManagerFactory.initialize()) {
    -				if (ApplicationKeyManagerFactory.getKeyStore() != null) {
    +			if (!DefaultKeyManagerFactory.initialize()) {
    +				if (DefaultKeyManagerFactory.getKeyStore() != null) {
     					// Report error condition?
     					throw new IOException("Failed to initialize PKI certificate keystore");
     				}
    
  • Ghidra/Framework/Generic/src/main/java/ghidra/net/PKIUtils.java+260 172 renamed
    @@ -42,15 +42,13 @@
     import generic.random.SecureRandomFactory;
     import ghidra.util.Msg;
     import ghidra.util.exception.AssertException;
    +import ghidra.util.exception.CancelledException;
     
     /**
    - * <code>ApplicationKeyManagerUtils</code> provides public methods for utilizing
    - * the application PKI key management, including access to trusted issuers
    - * (i.e., CA certificates), token signing and validation, and the ability to
    - * generate keystores for testing or when a self-signed certificate will
    - * suffice.
    + * {@link PKIUtils} provides supporting utilities for creating and accessing X509 certificate
    + * keystore files.
      */
    -public class ApplicationKeyManagerUtils {
    +public class PKIUtils {
     
     	public static final String RSA_TYPE = "RSA";
     
    @@ -69,193 +67,61 @@ public class ApplicationKeyManagerUtils {
     
     	static {
     		/**
    -		 * Bouncy Castle uses its BCStyle for X500Names which reverses Distingushed Name ordering.
    +		 * Bouncy Castle uses its BCStyle for X500Names which reverses Distinguished Name ordering.
     		 * This is resolved by setting the default to RFC4519 style to ensure compatibility with 
     		 * Java's internal implementation of X500Name.
     		 * <p>
     		 * Note that this could become an issue if this static default is adjusted elsewhere.
    -		 * It may be neccessary to set this at the start of all methods which rely on any of the
    +		 * It may be necessary to set this at the start of all methods which rely on any of the
     		 * BC code for X500 certificate processing.
     		 * 
     		 */
     		X500Name.setDefaultStyle(RFC4519Style.INSTANCE);
     	}
     
    -	private ApplicationKeyManagerUtils() {
    -		// no instantiation - static methods only
    -	}
    -
    -	/**
    -	 * Sign the supplied token byte array using an installed certificate from
    -	 * one of the specified authorities
    -	 * @param authorities trusted certificate authorities used to constrain client certificate
    -	 *   (may be null or empty array if CA constraint does not matter).
    -	 * @param token token byte array
    -	 * @return signed token object
    -	 * @throws NoSuchAlgorithmException algorithym associated within signing certificate not found
    -	 * @throws SignatureException failed to generate SignedToken
    -	 * @throws CertificateException error associated with signing certificate
    -	 */
    -	public static SignedToken getSignedToken(Principal[] authorities, byte[] token)
    -			throws NoSuchAlgorithmException, SignatureException, CertificateException {
    -
    -		PrivateKey privateKey = null;
    -		X509Certificate[] certificateChain = null;
    -		try {
    -			ApplicationKeyManagerFactory keyManagerFactory =
    -				ApplicationKeyManagerFactory.getInstance();
    -			for (KeyManager keyManager : keyManagerFactory.getKeyManagers()) {
    -				if (!(keyManager instanceof X509KeyManager)) {
    -					continue;
    -				}
    -				X509KeyManager x509KeyManager = (X509KeyManager) keyManager;
    -				String alias =
    -					x509KeyManager.chooseClientAlias(new String[] { RSA_TYPE }, authorities, null);
    -				if (alias != null) {
    -					privateKey = x509KeyManager.getPrivateKey(alias);
    -					certificateChain = x509KeyManager.getCertificateChain(alias);
    -					break;
    -				}
    -			}
    -
    -			if (privateKey == null || certificateChain == null) {
    -				CertificateException e =
    -					new CertificateException("suitable PKI certificate not found");
    -				e.printStackTrace();
    -				throw e;
    -			}
    -
    -			//
    -			// See JAVA Examples in a Nutshell (p.358) for use of Signer and
    -			// IdentityScope classes
    -			//
    -
    -			String algorithm = certificateChain[0].getSigAlgName();
    -			Signature sig = Signature.getInstance(algorithm);
    -			try {
    -				sig.initSign(privateKey);
    -			}
    -			catch (InvalidKeyException e) {
    -				throw new CertificateException("suitable PKI certificate not found", e);
    -			}
    -			sig.update(token);
    -
    -			return new SignedToken(token, sig.sign(), certificateChain, algorithm);
    -		}
    -		finally {
    -			if (privateKey != null) {
    -				// Note: Keystore destroy only supported in Java 1.8
    -				try {
    -					privateKey.destroy();
    -				}
    -				catch (DestroyFailedException e) {
    -					// ignore - may not be supported by all keystores
    -				}
    -			}
    -		}
    -	}
    -
    -	/**
    -	 * Verify that the specified sigBytes reflect my signature of the specified token.
    -	 * @param authorities trusted certificate authorities used to constrain client certificate
    -	 *   (may be null or empty array if CA constraint does not matter).
    -	 * @param token byte array token
    -	 * @param signature token signature
    -	 * @return true if signature is my signature
    -	 * @throws NoSuchAlgorithmException algorithym associated within signing certificate not found
    -	 * @throws SignatureException failed to generate SignedToken
    -	 * @throws CertificateException error associated with signing certificate
    -	 */
    -	public static boolean isMySignature(Principal[] authorities, byte[] token, byte[] signature)
    -			throws NoSuchAlgorithmException, SignatureException, CertificateException {
    -		SignedToken signedToken = getSignedToken(authorities, token);
    -		return Arrays.equals(signature, signedToken.signature);
    -	}
    -
     	/**
    -	 * Returns a list of trusted issuers (i.e., CA certificates) as established
    -	 * by the {@link ApplicationTrustManagerFactory}.
    -	 * @return array of trusted Certificate Authorities
    -	 * @throws CertificateException if failed to properly initialize trust manager
    -	 * due to CA certificate error(s).
    +	 * Establish X509TrustManager for the specified CA certificate storage.
    +	 * 
    +	 * @param caCertsFile CA certificates storage file
    +	 * @return X509TrustManager
    +	 * @throws CancelledException if password entry was cancelled
    +	 * @throws GeneralSecurityException if error occured during truststore initialization
    +	 * @throws IOException if file read error occurs
     	 */
    -	public static X500Principal[] getTrustedIssuers() throws CertificateException {
    +	public static X509TrustManager getTrustManager(File caCertsFile)
    +			throws CancelledException, GeneralSecurityException, IOException {
     
    -		TrustManager[] trustManagers = ApplicationTrustManagerFactory.getTrustManagers();
    -		if (ApplicationTrustManagerFactory.hasCertError()) {
    -			throw new CertificateException("failed to load CA certs",
    -				ApplicationTrustManagerFactory.getCertError());
    +		if (!caCertsFile.isFile()) {
    +			throw new FileNotFoundException(
    +				"CA Certificates file not found: " + caCertsFile.getAbsolutePath());
     		}
     
    -		Set<X500Principal> set = new HashSet<>();
    -
    -		boolean openTrust = true;
    -		for (TrustManager trustManager : trustManagers) {
    -			if (!(trustManager instanceof X509TrustManager)) {
    -				Msg.warn(ApplicationKeyManagerUtils.class,
    -					"Unexpected trust manager implementation: " +
    -						trustManager.getClass().getName());
    -				openTrust = false;
    -				continue;
    -			}
    -			X509TrustManager x509TrustManager = (X509TrustManager) trustManager;
    -			X509Certificate[] acceptedIssuers = x509TrustManager.getAcceptedIssuers();
    -			if (acceptedIssuers != null && acceptedIssuers.length != 0) {
    -				openTrust = false;
    -				for (X509Certificate trustedCert : acceptedIssuers) {
    -					set.add(trustedCert.getSubjectX500Principal());
    -				}
    +		KeyStore keyStore = PKIUtils.loadCertificateStore(caCertsFile.getAbsolutePath());
    +		TrustManagerFactory tmf =
    +			TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
    +		tmf.init(keyStore);
    +
    +		X509TrustManager trustManager = null;
    +		TrustManager[] trustManagers = tmf.getTrustManagers();
    +		for (TrustManager trustManager2 : trustManagers) {
    +			if (trustManager2 instanceof X509TrustManager mgr) {
    +				//ApplicationKeyStore.logCerts(mgr.getAcceptedIssuers());
    +				trustManager = mgr;
    +				break;
     			}
     		}
     
    -		if (openTrust) {
    -			return null;// trust all authorities
    -		}
    -
    -		X500Principal[] principals = new X500Principal[set.size()];
    -		return set.toArray(principals);
    -	}
    -
    -	/**
    -	 * Validate a client certificate ensuring that it is not expired and is
    -	 * trusted based upon the active trust managers.
    -	 * @param certChain X509 certificate chain
    -	 * @param authType authentication type (i.e., "RSA")
    -	 * @throws CertificateException if certificate validation fails
    -	 */
    -	public static void validateClient(X509Certificate[] certChain, String authType)
    -			throws CertificateException {
    -
    -		CertificateException checkFailure = null;
    -
    -		TrustManager[] trustManagers = ApplicationTrustManagerFactory.getTrustManagers();
    -		if (ApplicationTrustManagerFactory.hasCertError()) {
    -			throw new CertificateException("failed to load CA certs",
    -				ApplicationTrustManagerFactory.getCertError());
    +		if (trustManager == null) {
    +			throw new CertStoreException(
    +				"Failed to load X509 TrustManager from " + caCertsFile.getAbsolutePath());
     		}
     
    -		for (TrustManager trustManager : trustManagers) {
    -			if (!(trustManager instanceof X509TrustManager)) {
    -				continue;
    -			}
    -			X509TrustManager x509TrustManager = (X509TrustManager) trustManager;
    -
    -			try {
    -				x509TrustManager.checkClientTrusted(certChain, authType);
    -				checkFailure = null;
    -				break;
    -			}
    -			catch (CertificateException e) {
    -				checkFailure = e;
    -			}
    -		}
    -		if (checkFailure != null) {
    -			throw checkFailure;// check failed - throw last failure
    -		}
    +		return trustManager;
     	}
     
     	/**
     	 * Pack ordered list of certs to create a certificate chain array
    +	 * 
     	 * @param cert primary certificate
     	 * @param caCerts CA certificate chain.
     	 * @return ordered certificate chain
    @@ -269,6 +135,7 @@ private static Certificate[] makeCertificateChain(Certificate cert, Certificate.
     
     	/**
     	 * Export X.509 certificates to the specified outFile.
    +	 * 
     	 * @param certificates certificates to be stored 
     	 * @param outFile output file
     	 * @throws IOException if error occurs writing to outFile
    @@ -300,6 +167,7 @@ public static void exportX509Certificates(Certificate[] certificates, File outFi
     	/**
     	 * Generate a new {@link X509Certificate} with RSA {@link KeyPair} and create/update a {@link KeyStore}
     	 * optionally backed by a keyFile.  
    +	 * 
     	 * @param alias entry alias with keystore
     	 * @param dn distinguished name (e.g., "CN=Ghidra Test, O=Ghidra, OU=Test, C=US" )
     	 * @param durationDays number of days which generated certificate should remain valid
    @@ -407,7 +275,7 @@ public ProtectionParameter getProtectionParameter() {
     					keyStore.store(out, protectedPassphrase);
     					out.flush();
     					out.getFD().sync();
    -					Msg.debug(ApplicationKeyManagerUtils.class,
    +					Msg.debug(PKIUtils.class,
     						out.getChannel().size() + " bytes written to key/cert file: " + keyFile);
     				}
     				catch (SyncFailedException e) {
    @@ -420,8 +288,7 @@ public ProtectionParameter getProtectionParameter() {
     				keyFile.setWritable(false);
     			}
     
    -			Msg.debug(ApplicationKeyManagerUtils.class,
    -				"Certificate Generated (" + alias + "): " + dn);
    +			Msg.debug(PKIUtils.class, "Certificate Generated (" + alias + "): " + dn);
     
     			return keyStore;
     		}
    @@ -441,6 +308,7 @@ public ProtectionParameter getProtectionParameter() {
     	/**
     	 * Generate a new {@link X509Certificate} with RSA {@link KeyPair} and create/update a {@link KeyStore}
     	 * optionally backed by a keyFile.  
    +	 * 
     	 * @param alias entry alias with keystore
     	 * @param dn distinguished name (e.g., "CN=Ghidra Test, O=Ghidra, OU=Test, C=US" )
     	 * @param durationDays number of days which generated certificate should remain valid
    @@ -477,4 +345,224 @@ public static final PrivateKeyEntry createKeyEntry(String alias, String dn, int
     		}
     	}
     
    +	/**
    +	 * Load the all certificates from the specified certificate store in a standard
    +	 * X.509 form (e.g., concatenation of Base64 encoded certificates: *.pem, *.crt, *.cer, *.der) 
    +	 * or Java JKS (*.jks) form.
    +	 * 
    +	 * @param certsPath certificate(s) storage file path
    +	 * @return KeyStore containing certificates
    +	 * @throws IOException if failure occurred reading and processing keystore file.
    +	 * @throws NoSuchAlgorithmException if the algorithm used to check the integrity of the 
    +	 * 			keystore cannot be found
    +	 * @throws CertificateException if any of the certificates in the keystore could not be loaded 
    +	 * @throws KeyStoreException if a general error occurred opening/processing keystore
    +	 */
    +	public static KeyStore loadCertificateStore(String certsPath)
    +			throws IOException, KeyStoreException, NoSuchAlgorithmException, CertificateException {
    +
    +		int certCount = 0;
    +
    +		KeyStore store = KeyStore.getInstance(KeyStore.getDefaultType());
    +		store.load(null);
    +
    +		// Attempt to read certificates in Base64 encoded form
    +		InputStream fis = new FileInputStream(certsPath);
    +		BufferedInputStream bis = new BufferedInputStream(fis);
    +
    +		try {
    +			CertificateFactory cf = CertificateFactory.getInstance("X.509");
    +			while (bis.available() > 0) {
    +				try {
    +					Certificate cert = cf.generateCertificate(bis);
    +					if (cert instanceof X509Certificate) {
    +						X509Certificate x509Cert = (X509Certificate) cert;
    +						String name = getCommonName(x509Cert.getSubjectX500Principal());
    +						store.setCertificateEntry(name, cert);
    +						++certCount;
    +					}
    +				}
    +				catch (CertificateException e) {
    +					// Must handle blank lines at bottom of file
    +					Throwable cause = e.getCause();
    +					if (cause != null && "Empty input".equals(cause.getMessage())) {
    +						break; // end of file
    +					}
    +					throw e;
    +				}
    +			}
    +		}
    +		finally {
    +			bis.close();
    +		}
    +
    +		if (certCount == 0) {
    +			// Processing JKS files above produce "Empty input", if no certs read
    +			// try reading as keystore without password 
    +			return getKeyStoreInstance(certsPath, null);
    +		}
    +		return store;
    +	}
    +
    +	/**
    +	 * Attempt to load a client/server keystore in a PKCS12 form (*.p12, *.pks, *.pfx) or 
    +	 * Java JKS (*.jks) form.
    +	 * 
    +	 * @param keystorePath JKS or PKCS12 keystore file path
    +	 * @param password keystore password
    +	 * @return keystore instance
    +	 * @throws IOException if failure occurred reading and processing keystore file or if the 
    +	 * 			given password was incorrect. If the error is due to a wrong password, the 
    +	 * 			{@link Throwable#getCause cause} of the {@code IOException} should be an
    +	 * 			{@code UnrecoverableKeyException}
    +	 * @throws NoSuchAlgorithmException if the algorithm used to check the integrity of the 
    +	 * 			keystore cannot be found
    +	 * @throws CertificateException if any of the certificates in the keystore could not be loaded 
    +	 * @throws KeyStoreException if a general error occurred opening/processing keystore
    +	 */
    +	public static synchronized KeyStore getKeyStoreInstance(String keystorePath, char[] password)
    +			throws IOException, KeyStoreException, NoSuchAlgorithmException, CertificateException {
    +
    +		String type = PKIUtils.detectKeyStoreType(keystorePath);
    +		if (type == null) {
    +			throw new KeyStoreException("Unsupported PKI key store file type: " + keystorePath);
    +		}
    +
    +		KeyStore ks = KeyStore.getInstance(type);
    +
    +		InputStream fis = new FileInputStream(keystorePath);
    +		BufferedInputStream bis = new BufferedInputStream(fis);
    +		try {
    +			ks.load(bis, password);
    +		}
    +		finally {
    +			bis.close();
    +		}
    +		return ks;
    +	}
    +
    +	/**
    +	 * Attempt to detect PKI KeyStore type ("JKS" or "PKCS12") for the specified file.
    +	 * 
    +	 * @param keystorePath key store file path
    +	 * @return "JKS", "PKCS12" or null
    +	 * @throws IOException if file read error occurs
    +	 */
    +	public static String detectKeyStoreType(String keystorePath) throws IOException {
    +		try (FileInputStream fis = new FileInputStream(keystorePath)) {
    +			byte[] header = new byte[4];
    +			int read = fis.read(header);
    +			if (read < 4) {
    +				return null;
    +			}
    +
    +			// Check for JKS magic number: FEEDFEED
    +			if ((header[0] & 0xFF) == 0xFE && (header[1] & 0xFF) == 0xED &&
    +				(header[2] & 0xFF) == 0xFE && (header[3] & 0xFF) == 0xED) {
    +				return "JKS";
    +			}
    +
    +			// Check for PKCS12: starts with 0x30 0x82
    +			if ((header[0] & 0xFF) == 0x30 && (header[1] & 0xFF) == 0x82) {
    +				return "PKCS12";
    +			}
    +
    +			return null;
    +		}
    +	}
    +
    +	/**
    +	 * Extract Common Name (CN) from specified principal subject Distinguished Name (DN)
    +	 * 
    +	 * @param subject X.509 certificate subject
    +	 * @return Common Name or full subject name if unable to extract CN from DN
    +	 */
    +	private static String getCommonName(Principal subject) {
    +
    +		// Subject name should be distinguished-name (DN) which starts with common-name (CN)
    +		String name = subject.getName();
    +		int commaIndex = name.indexOf(',');
    +		String firstElement = commaIndex < 0 ? name : name.substring(0, commaIndex);
    +
    +		int equalsIndex = firstElement.indexOf('=');
    +		if (equalsIndex <= 0) {
    +			return name; // bad common name
    +		}
    +
    +		String fieldName = firstElement.substring(0, equalsIndex).trim();
    +		String fieldValue = firstElement.substring(equalsIndex + 1).trim();
    +
    +		if (!fieldName.equalsIgnoreCase("CN")) {
    +			return name; // bad common name
    +		}
    +
    +		return fieldValue;
    +	}
    +
    +	/**
    +	 * Log all X509 certificates contained within keystore
    +	 * 
    +	 * @param keyStore certificate keystore
    +	 */
    +	static void logCerts(KeyStore keyStore) {
    +		try {
    +			Enumeration<String> aliases = keyStore.aliases();
    +			while (aliases.hasMoreElements()) {
    +				String alias = aliases.nextElement();
    +				Certificate certificate = keyStore.getCertificate(alias);
    +				if (certificate == null) {
    +					continue;
    +				}
    +				else if (certificate instanceof X509Certificate) {
    +					logCert(alias, (X509Certificate) certificate);
    +				}
    +				else {
    +					Msg.warn(PKIUtils.class, "Ignore unrecognized certificate: alias=" + alias +
    +						", type=" + certificate.getType());
    +				}
    +			}
    +		}
    +		catch (KeyStoreException e) {
    +			Msg.error(PKIUtils.class, "KeyStore failure", e);
    +		}
    +	}
    +
    +	/**
    +	 * Log all X509 certificates contained within array
    +	 * 
    +	 * @param x509Certs array of certificates
    +	 */
    +	public static void logCerts(X509Certificate[] x509Certs) {
    +		for (X509Certificate x509Cert : x509Certs) {
    +			logCert(null, x509Cert);
    +		}
    +	}
    +
    +	/**
    +	 * Log specified X509 certificate details
    +	 * 
    +	 * @param alias certificate alias or null if not applicable
    +	 * @param x509Cert X509 certificate
    +	 */
    +	static void logCert(String alias, X509Certificate x509Cert) {
    +
    +		X500Principal subj = x509Cert.getSubjectX500Principal();
    +		X500Principal issuer = x509Cert.getIssuerX500Principal();
    +
    +		Date now = new Date();
    +
    +		String label = alias != null ? (alias + ": ") : "";
    +		if (now.compareTo(x509Cert.getNotAfter()) > 0) {
    +			Msg.warn(PKIUtils.class,
    +				"   " + label + getCommonName(subj) + ", issued by " + getCommonName(issuer) +
    +					", S/N " + x509Cert.getSerialNumber().toString(16) + ", expired " +
    +					x509Cert.getNotAfter() + " **EXPIRED**");
    +		}
    +		else {
    +			Msg.info(PKIUtils.class,
    +				"   " + label + getCommonName(subj) + ", issued by " + getCommonName(issuer) +
    +					", S/N " + x509Cert.getSerialNumber().toString(16) + ", expires " +
    +					x509Cert.getNotAfter());
    +		}
    +	}
     }
    
  • Ghidra/Framework/Generic/src/test/java/ghidra/net/ApplicationKeyManagerFactoryTest.java+16 23 modified
    @@ -4,9 +4,9 @@
      * Licensed under the Apache License, Version 2.0 (the "License");
      * you may not use this file except in compliance with the License.
      * You may obtain a copy of the License at
    - * 
    + *
      *      http://www.apache.org/licenses/LICENSE-2.0
    - * 
    + *
      * Unless required by applicable law or agreed to in writing, software
      * distributed under the License is distributed on an "AS IS" BASIS,
      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    @@ -21,7 +21,6 @@
     import java.security.*;
     import java.security.cert.X509Certificate;
     
    -import javax.net.ssl.KeyManager;
     import javax.net.ssl.X509ExtendedKeyManager;
     
     import org.junit.*;
    @@ -73,8 +72,8 @@ public void setUp() throws Exception {
     		keystoreFile = createTempFile("test-key", ".p12");
     		keystoreFile.delete();
     
    -		ApplicationKeyManagerUtils.createKeyStore(ALIAS, TEST_IDENTITY, 2, null, keystoreFile,
    -			"PKCS12", null, TEST_PWD.toCharArray());
    +		PKIUtils.createKeyStore(ALIAS, TEST_IDENTITY, 2, null, keystoreFile, "PKCS12", null,
    +			TEST_PWD.toCharArray());
     
     		ApplicationKeyManagerFactory.setKeyStorePasswordProvider(passwordProvider);
     	}
    @@ -89,45 +88,39 @@ public void tearDown() throws Exception {
     	@Test
     	public void testCancelledPasswordOnSetCertificate() throws Exception {
     
    -		assertNull(ApplicationKeyManagerFactory.getKeyStore());
    -		ApplicationKeyManagerFactory instance = ApplicationKeyManagerFactory.getInstance();
    -		KeyManager[] keyManagers = instance.getKeyManagers();
    -		assertEquals(1, keyManagers.length);
    -		assertTrue("", keyManagers[0] instanceof X509ExtendedKeyManager);
    -		X509ExtendedKeyManager keyManager = (X509ExtendedKeyManager) keyManagers[0];
    +		assertNull(DefaultKeyManagerFactory.getKeyStore());
    +		X509ExtendedKeyManager keyManager = DefaultKeyManagerFactory.getKeyManager();
    +		assertNotNull(keyManager);
     
     		// verify that no certs are installed
     		assertNull(keyManager.getCertificateChain(ALIAS));
     		assertNull(keyManager.getClientAliases("RSA", null));
     
     		passwordProvider.cancelNextEntry();
     
    -		ApplicationKeyManagerFactory.setKeyStore(keystoreFile.getAbsolutePath(), false);
    +		DefaultKeyManagerFactory.setDefaultKeyStore(keystoreFile.getAbsolutePath(), false);
     
     		// verify that no certs are installed
    -		assertEquals(null, ApplicationKeyManagerFactory.getKeyStore());
    +		assertEquals(null, DefaultKeyManagerFactory.getKeyStore());
     		assertNull(keyManager.getCertificateChain(ALIAS));
     		assertNull(keyManager.getClientAliases("RSA", null));
     	}
     
     	@Test
     	public void testSetClearCertificate() throws Exception {
     
    -		assertNull(ApplicationKeyManagerFactory.getKeyStore());
    -		ApplicationKeyManagerFactory instance = ApplicationKeyManagerFactory.getInstance();
    -		KeyManager[] keyManagers = instance.getKeyManagers();
    -		assertEquals(1, keyManagers.length);
    -		assertTrue("", keyManagers[0] instanceof X509ExtendedKeyManager);
    -		X509ExtendedKeyManager keyManager = (X509ExtendedKeyManager) keyManagers[0];
    +		assertNull(DefaultKeyManagerFactory.getKeyStore());
    +		X509ExtendedKeyManager keyManager = DefaultKeyManagerFactory.getKeyManager();
    +		assertNotNull(keyManager);
     
     		// verify that no certs are installed
     		assertNull(keyManager.getCertificateChain(ALIAS));
     		assertNull(keyManager.getClientAliases("RSA", null));
     
    -		ApplicationKeyManagerFactory.setKeyStore(keystoreFile.getAbsolutePath(), false);
    +		DefaultKeyManagerFactory.setDefaultKeyStore(keystoreFile.getAbsolutePath(), false);
     
     		// verify that generated cert is installed
    -		assertEquals(keystoreFile.getAbsolutePath(), ApplicationKeyManagerFactory.getKeyStore());
    +		assertEquals(keystoreFile.getAbsolutePath(), DefaultKeyManagerFactory.getKeyStore());
     		X509Certificate[] chain = keyManager.getCertificateChain(ALIAS);
     		assertNotNull(chain);
     		String[] aliases = keyManager.getClientAliases("RSA", new Principal[0]); // any CA allowed
    @@ -158,10 +151,10 @@ public void testSetClearCertificate() throws Exception {
     		}
     
     		// clear keystore
    -		ApplicationKeyManagerFactory.setKeyStore(null, false);
    +		DefaultKeyManagerFactory.setDefaultKeyStore(null, false);
     
     		// verify that no certs are installed
    -		assertNull(ApplicationKeyManagerFactory.getKeyStore());
    +		assertNull(DefaultKeyManagerFactory.getKeyStore());
     		assertNull(keyManager.getCertificateChain(ALIAS));
     		assertNull(keyManager.getClientAliases("RSA", null));
     
    
  • Ghidra/Framework/Project/src/main/java/ghidra/framework/main/EditActionManager.java+18 18 modified
    @@ -4,9 +4,9 @@
      * Licensed under the Apache License, Version 2.0 (the "License");
      * you may not use this file except in compliance with the License.
      * You may obtain a copy of the License at
    - * 
    + *
      *      http://www.apache.org/licenses/LICENSE-2.0
    - * 
    + *
      * Unless required by applicable law or agreed to in writing, software
      * distributed under the License is distributed on an "AS IS" BASIS,
      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    @@ -24,8 +24,8 @@
     import docking.widgets.OptionDialog;
     import docking.widgets.filechooser.GhidraFileChooser;
     import docking.widgets.filechooser.GhidraFileChooserMode;
    -import ghidra.net.ApplicationKeyManagerFactory;
    -import ghidra.net.ApplicationKeyManagerUtils;
    +import ghidra.net.DefaultKeyManagerFactory;
    +import ghidra.net.PKIUtils;
     import ghidra.util.HelpLocation;
     import ghidra.util.filechooser.ExtensionFileFilter;
     import ghidra.util.filechooser.GhidraFileFilter;
    @@ -38,7 +38,7 @@ class EditActionManager {
     	 * PKCS Private Key/Certificate File Filter
     	 */
     	public static final GhidraFileFilter CERTIFICATE_FILE_FILTER =
    -		new ExtensionFileFilter(ApplicationKeyManagerUtils.PKCS_FILE_EXTENSIONS, "PKCS Key File");
    +		new ExtensionFileFilter(PKIUtils.PKCS_FILE_EXTENSIONS, "PKCS Key File");
     
     	private FrontEndPlugin plugin;
     	private FrontEndTool tool;
    @@ -68,8 +68,8 @@ public void actionPerformed(ActionContext context) {
     // ACTIONS - auto generated
     		editPluginPathAction.setEnabled(true);
     
    -		editPluginPathAction.setMenuBarData(new MenuData(new String[] { ToolConstants.MENU_EDIT,
    -			"Plugin Path..." }, "GEdit"));
    +		editPluginPathAction.setMenuBarData(
    +			new MenuData(new String[] { ToolConstants.MENU_EDIT, "Plugin Path..." }, "GEdit"));
     
     		editCertPathAction = new DockingAction("Set PKI Certificate", plugin.getName()) {
     			@Override
    @@ -80,8 +80,8 @@ public void actionPerformed(ActionContext context) {
     // ACTIONS - auto generated
     		editCertPathAction.setEnabled(true);
     
    -		editCertPathAction.setMenuBarData(new MenuData(new String[] { ToolConstants.MENU_EDIT,
    -			"Set PKI Certificate..." }, "PKI"));
    +		editCertPathAction.setMenuBarData(new MenuData(
    +			new String[] { ToolConstants.MENU_EDIT, "Set PKI Certificate..." }, "PKI"));
     
     		clearCertPathAction = new DockingAction("Clear PKI Certificate", plugin.getName()) {
     			@Override
    @@ -90,13 +90,13 @@ public void actionPerformed(ActionContext context) {
     			}
     		};
     // ACTIONS - auto generated
    -		clearCertPathAction.setEnabled(ApplicationKeyManagerFactory.getKeyStore() != null);
    +		clearCertPathAction.setEnabled(DefaultKeyManagerFactory.getKeyStore() != null);
     
    -		clearCertPathAction.setMenuBarData(new MenuData(new String[] { ToolConstants.MENU_EDIT,
    -			"Clear PKI Certificate..." }, "PKI"));
    +		clearCertPathAction.setMenuBarData(new MenuData(
    +			new String[] { ToolConstants.MENU_EDIT, "Clear PKI Certificate..." }, "PKI"));
     
    -		clearCertPathAction.setHelpLocation(new HelpLocation("FrontEndPlugin",
    -			"Set_PKI_Certificate"));
    +		clearCertPathAction
    +				.setHelpLocation(new HelpLocation("FrontEndPlugin", "Set_PKI_Certificate"));
     		tool.addAction(editCertPathAction);
     		tool.addAction(clearCertPathAction);
     		tool.addAction(editPluginPathAction);
    @@ -112,7 +112,7 @@ private void editPluginPath() {
     
     	private void clearCertPath() {
     
    -		String path = ApplicationKeyManagerFactory.getKeyStore();
    +		String path = DefaultKeyManagerFactory.getKeyStore();
     		if (path == null) {
     			// unexpected
     			clearCertPathAction.setEnabled(false);
    @@ -124,7 +124,7 @@ private void clearCertPath() {
     			return;
     		}
     
    -		ApplicationKeyManagerFactory.setKeyStore(null, true);
    +		DefaultKeyManagerFactory.setDefaultKeyStore(null, true);
     		clearCertPathAction.setEnabled(false);
     	}
     
    @@ -134,7 +134,7 @@ private void editCertPath() {
     
     		File dir = null;
     		File oldFile = null;
    -		String path = ApplicationKeyManagerFactory.getKeyStore();
    +		String path = DefaultKeyManagerFactory.getKeyStore();
     		if (path != null) {
     			oldFile = new File(path);
     			dir = oldFile.getParentFile();
    @@ -163,7 +163,7 @@ private void editCertPath() {
     			if (file == null) {
     				return; // cancelled
     			}
    -			ApplicationKeyManagerFactory.setKeyStore(file.getAbsolutePath(), true);
    +			DefaultKeyManagerFactory.setDefaultKeyStore(file.getAbsolutePath(), true);
     			clearCertPathAction.setEnabled(true);
     			validInput = true;
     		}
    
  • Ghidra/Framework/Project/src/main/java/ghidra/framework/main/ProjectActionManager.java+1 0 modified
    @@ -28,6 +28,7 @@
     import docking.widgets.OptionDialog;
     import docking.widgets.PasswordChangeDialog;
     import docking.widgets.filechooser.GhidraFileChooser;
    +import generic.hash.HashUtilities;
     import ghidra.framework.client.ClientUtil;
     import ghidra.framework.client.RepositoryAdapter;
     import ghidra.framework.model.*;
    
  • Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/framework/client/GhidraServerSerialFilterFailureTest.java+7 8 modified
    @@ -4,9 +4,9 @@
      * Licensed under the Apache License, Version 2.0 (the "License");
      * you may not use this file except in compliance with the License.
      * You may obtain a copy of the License at
    - * 
    + *
      *      http://www.apache.org/licenses/LICENSE-2.0
    - * 
    + *
      * Unless required by applicable law or agreed to in writing, software
      * distributed under the License is distributed on an "AS IS" BASIS,
      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    @@ -33,7 +33,7 @@
     import generic.test.category.PortSensitiveCategory;
     import ghidra.framework.model.ServerInfo;
     import ghidra.framework.remote.GhidraServerHandle;
    -import ghidra.net.ApplicationKeyManagerFactory;
    +import ghidra.net.DefaultKeyManagerFactory;
     import ghidra.server.remote.ServerTestUtil;
     import ghidra.test.AbstractGhidraHeadlessIntegrationTest;
     import ghidra.util.task.TaskMonitor;
    @@ -46,7 +46,7 @@ public class GhidraServerSerialFilterFailureTest extends AbstractGhidraHeadlessI
     
     	@Before
     	public void setUp() throws Exception {
    -		System.clearProperty(ApplicationKeyManagerFactory.KEYSTORE_PATH_PROPERTY);
    +		System.clearProperty(DefaultKeyManagerFactory.KEYSTORE_PATH_PROPERTY);
     	}
     
     	@After
    @@ -79,7 +79,6 @@ private void startServer(int authMode, boolean altLoginName, boolean enableSSH,
     			enableAnonymous);
     	}
     
    -
     	static class BogusPrincipal implements Principal, java.io.Serializable {
     
     		private String username;
    @@ -110,10 +109,10 @@ public void testSerializationFailure() throws Exception {
     		startServer(-1, false, false, false);
     
     		ServerInfo server = new ServerInfo("localhost", ServerTestUtil.GHIDRA_TEST_SERVER_PORT);
    -		
    +
     		GhidraServerHandle serverHandle =
     			ServerConnectTask.getGhidraServerHandle(server, TaskMonitor.DUMMY);
    -		
    +
     		try {
     			serverHandle.getRepositoryServer(getBogusUserSubject(), new Callback[0]);
     			fail("serial filter rejection failed to perform");
    @@ -125,7 +124,7 @@ public void testSerializationFailure() throws Exception {
     			assertTrue("expected remote invalid class exceptionn",
     				cause instanceof InvalidClassException);
     		}
    -		
    +
     	}
     
     }
    
  • Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/server/remote/ServerTestUtil.java+14 14 modified
    @@ -29,6 +29,7 @@
     
     import org.apache.commons.lang3.RandomStringUtils;
     
    +import generic.hash.HashUtilities;
     import generic.test.*;
     import ghidra.framework.Application;
     import ghidra.framework.client.*;
    @@ -424,9 +425,9 @@ public static synchronized void startServer(String dirPath, int port, int authMo
     			"     Enable Anonymous Login: " + enableAnonymousAuthentication);
     
     		// Force client-side use of newly generated CA certificates
    -		System.setProperty(ApplicationTrustManagerFactory.GHIDRA_CACERTS_PATH_PROPERTY,
    +		System.setProperty(DefaultTrustManagerFactory.GHIDRA_CACERTS_PATH_PROPERTY,
     			getTestPkiCACertsPath());
    -		SSLContextInitializer.initialize(true);
    +		DefaultSSLContextInitializer.initialize(true);
     
     		ArrayList<String> argList = new ArrayList<>();
     		String javaCommand =
    @@ -441,11 +442,11 @@ public static synchronized void startServer(String dirPath, int port, int authMo
     		argList.add("-Xdebug");
     		argList.add("-Xnoagent");
     		argList.add("-Djava.compiler=NONE");
    -		argList.add("-D" + ApplicationTrustManagerFactory.GHIDRA_CACERTS_PATH_PROPERTY + "=" +
    +		argList.add("-D" + DefaultTrustManagerFactory.GHIDRA_CACERTS_PATH_PROPERTY + "=" +
     			getTestPkiCACertsPath());
    -		argList.add("-D" + ApplicationKeyManagerFactory.KEYSTORE_PATH_PROPERTY + "=" +
    +		argList.add("-D" + DefaultKeyManagerFactory.KEYSTORE_PATH_PROPERTY + "=" +
     			getTestPkiServerKeystorePath());
    -		argList.add("-D" + ApplicationKeyManagerFactory.KEYSTORE_PASSWORD_PROPERTY + "=" +
    +		argList.add("-D" + DefaultKeyManagerFactory.KEYSTORE_PASSWORD_PROPERTY + "=" +
     			TEST_PKI_SERVER_PASSPHRASE);
     		argList.add("-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=*:18202"); // *: for remote debug support
     		argList.add("-DSystemUtilities.isTesting=true");
    @@ -622,7 +623,7 @@ public static RepositoryServerAdapter getServerAdapter(File serverRoot, String[]
     
     	public static synchronized void disposeServer() {
     
    -		System.setProperty(ApplicationTrustManagerFactory.GHIDRA_CACERTS_PATH_PROPERTY, "");
    +		System.setProperty(DefaultTrustManagerFactory.GHIDRA_CACERTS_PATH_PROPERTY, "");
     
     		if (serverProcess != null) {
     
    @@ -939,23 +940,22 @@ private static void generatePkiCerts() throws Exception {
     
     		// Generate CA certificate and keystore
     		Msg.info(ServerTestUtil.class, "Generating self-signed CA cert: " + caPath);
    -		PrivateKeyEntry caEntry =
    -			ApplicationKeyManagerUtils.createKeyEntry("test-CA", TEST_PKI_CA_DN, 2, null, null,
    -				"PKCS12", null, ApplicationKeyManagerFactory.DEFAULT_PASSWORD.toCharArray());
    -		ApplicationKeyManagerUtils.exportX509Certificates(caEntry.getCertificateChain(), caFile);
    +		PrivateKeyEntry caEntry = PKIUtils.createKeyEntry("test-CA", TEST_PKI_CA_DN, 2, null, null,
    +			"PKCS12", null, DefaultKeyManagerFactory.DEFAULT_PASSWORD.toCharArray());
    +		PKIUtils.exportX509Certificates(caEntry.getCertificateChain(), caFile);
     
     		// Generate User/Client certificate and keystore
     		Msg.info(ServerTestUtil.class, "Generating test user key/cert (signed by test-CA, pwd: " +
     			TEST_PKI_USER_PASSPHRASE + "): " + userKeystorePath);
    -		ApplicationKeyManagerUtils.createKeyEntry("test-sig", TEST_PKI_USER_DN, 2, caEntry,
    -			userKeystoreFile, "PKCS12", null, TEST_PKI_USER_PASSPHRASE.toCharArray());
    +		PKIUtils.createKeyEntry("test-sig", TEST_PKI_USER_DN, 2, caEntry, userKeystoreFile,
    +			"PKCS12", null, TEST_PKI_USER_PASSPHRASE.toCharArray());
     
     		// Generate Server certificate and keystore
     		Msg.info(ServerTestUtil.class, "Generating test server key/cert (signed by test-CA, pwd: " +
     			TEST_PKI_SERVER_PASSPHRASE + "): " + serverKeystorePath);
     
    -		ApplicationKeyManagerUtils.createKeyEntry("test-sig", TEST_PKI_SERVER_DN, 2, caEntry,
    -			serverKeystoreFile, "PKCS12", null, TEST_PKI_SERVER_PASSPHRASE.toCharArray());
    +		PKIUtils.createKeyEntry("test-sig", TEST_PKI_SERVER_DN, 2, caEntry, serverKeystoreFile,
    +			"PKCS12", null, TEST_PKI_SERVER_PASSPHRASE.toCharArray());
     	}
     
     	/**
    
79d8f164f8bb

Candidate release of source code.

300 files changed · +372534 9
  • DevGuide.md+275 0 added
    @@ -0,0 +1,275 @@
    +# Developer's Guide: Getting Started
    +
    +Install OpenJDK 11 and make sure it's the default java.
    +
    +Install Eclipse, at least version 2018-12, and ensure it is launched using OpenJDK 11.
    +Technically, you can launch with any JRE/JDK, but it's up to you ensure OpenJDK 11 is properly configured in Eclipse.
    +
    +Optionally install Gradle 5.0, and ensure it is launched using OpenJDK 11.
    +These instructions assume you are using the gradle wrapper, so adjust the commands accordingly if you choose to use your own Gradle installation.
    +
    +## Setup Repositories
    +
    +Of course, you may choose any directory for your working copy, but these instructions will assume you have cloned the repo to `~/git`.
    +Be sure to adjust the commands to match your chosen working directory if different than suggested:
    +
    +```bash
    +cd ~/git
    +git clone git@github.com:NationalSecurityAgency/ghidra.git
    +```
    +
    +Ghidra's build uses artifact named as available in Maven Central and Bintray JCenter, when possible.
    +Unfortunately, in some cases, the artifact or the particular version we desire is not available.
    +So, in addition to mavenCentral and jcenter, you must configure a flatDir-style repository for manually-downloaded dependencies.
    +
    +Create `~/.gradle/init.d/repos.gradle` with the following contents:
    +
    +```groovy
    +ext.HOME = System.getProperty('user.home')
    +
    +allprojects {
    +    repositories {
    +        mavenCentral()
    +        jcenter()
    +        flatDir name:'flat', dirs:["$HOME/flatRepo"]
    +    }
    +}
    +```
    +
    +You should also create the `~/flatRepo` folder to hold the manually-downloaded dependencies:
    +
    +```bash
    +mkdir ~/flatRepo
    +```
    +
    +If you prefer not to modify your user-wide Gradle configuration, you may use
    +Gradle's other init script facilities, but you're on your own.
    +
    +## Get Dependencies for FileFormats:
    +
    +Download `dex-tools-2.0.zip` from the dex2jar project's releases page on GitHub.
    +Unpack the `dex-*.jar` files from the `lib` directory to `~/flatRepo`:
    +
    +```bash
    +cd ~/Downloads   # Or wherever
    +curl -OL https://github.com/pxb1988/dex2jar/releases/download/2.0/dex-tools-2.0.zip
    +unzip dex-tools-2.0.zip
    +cp dex2jar-2.0/lib/dex-*.jar ~/flatRepo/
    +
    +```
    +
    +Download `AXMLPrinter2.jar` from the "android4me" archive on code.google.com.
    +Place it in `~/flatRepo`:
    +
    +```bash
    +cd ~/flatRepo
    +curl -OL https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/android4me/AXMLPrinter2.jar
    +```
    +
    +## Get Dependencies for DMG:
    +
    +Download `hfsexplorer-0_21-bin.zip` from www.catacombae.org.
    +Unpack the `lib` directory to `~/flatRepo.`:
    +
    +```bash
    +cd ~/Downloads   # Or wherever
    +curl -OL https://sourceforge.net/projects/catacombae/files/HFSExplorer/0.21/hfsexplorer-0_21-bin.zip
    +mkdir hfsx
    +cd hfsx
    +unzip ../hfsexplorer-0_21-bin.zip
    +cd lib
    +cp csframework.jar hfsx_dmglib.jar hfsx.jar iharder-base64.jar ~/flatRepo/
    +```
    +
    +## Import Gradle Project
    +
    +At this point, you may import Ghidra into Eclipse using the integrated BuildShip plugin.
    +If you prefer another IDE, there's no reason it shouldn't work, but you're on your own.
    +Note that the GhidraDevPlugin requires Eclipse PDE.
    +Close this project to clean up the errors, unless you are developing the GhidraDevPlugin.
    +You may see build path errors until the environment is properly prepared, as described below.
    +
    +## Prepare the Environment
    +
    +There are a few preparatory tasks you should execute before, or immediately after, importing the project.
    +These tasks will build and index the online help, and place it somewhere accessible to Ghidra when launched from Eclipse, among other things.
    +This task also attempts to unpack some SDKs and/or larger dependencies required by Ghidra.
    +We do not provide these packages out-of-the-box because of technical and legal constraints on our distributing them.
    +These include the Eclipse CDT, PyDev for Eclipse, and "Yet another Java service wrapper."
    +If you would like to build the dependent modules, please see the relevant sections below.
    +For now, we will exclude the affected unpack tasks.
    +From the project root, execute:
    +
    +```bash
    +./gradlew prepDev -x yajswDevUnpack
    +```
    +
    +Optionally, to pre-compile all the language modules, you may also execute:
    +
    +```bash
    +./gradlew sleighCompile
    +```
    +
    +Refresh the Gradle project in Eclipse.
    +You should not see any errors at this point, and you can accomplish many development tasks.
    +However, some features of Ghidra will not be functional until further steps are taken.
    +
    +### Building the natives
    +
    +Some of Ghidra's components are built for the native platform.
    +We currently support Linux, macOS, and Windows 64-bit x86 systems.
    +Others should be possible, but we do not support them.
    +
    +#### decompile
    +
    +Install bison and flex.
    +Now build using Gradle:
    +
    +On Linux:
    +
    +```bash
    +./gradlew decompileLinux64Executable
    +```
    +On macOS:
    +
    +```bash
    +./gradlew decompileOsx64Executable
    +```
    +
    +On Windows:
    +
    +```cmd
    +gradlew decompileWin64Executable
    +```
    +
    +#### demangler_gnu
    +
    +Build using Gradle:
    +
    +On Linux:
    +
    +```bash
    +./gradlew demangler_gnuLinux64Executable
    +```
    +On macOS:
    +
    +```bash
    +./gradlew demangler_gnuOsx64Executable
    +```
    +
    +On Windows:
    +
    +```cmd
    +gradlew demangler_gnuWin64Executable
    +```
    +
    +#### sleigh
    +
    +The sleigh compiler has been ported to Java, and Ghidra will automatically compile slaspec files that it finds are out of date.
    +The native sleigh compiler may still be useful for those who'd like quicker feedback by compiling from the command line. To build the native sleigh compiler, install bison and flex.
    +Now, use Gradle:
    +
    +On Linux:
    +
    +```bash
    +./gradlew sleighLinux64Executable
    +```
    +On macOS:
    +
    +```bash
    +./gradlew sleighOsx64Executable
    +```
    +
    +On Windows:
    +
    +```cmd
    +gradlew sleighWin64Executable
    +```
    +
    +### Get Dependencies for GhidraDev
    +
    +Building the GhidraDev plugin for Eclipse requires the CDT and PyDev plugins for Eclipse.
    +Download `cdt-8.6.0.zip` from The Eclipse Foundation, and place it in a directory named:
    +`ghidra.bin/GhidraBuild/EclipsePlugins/GhidraDev/buildDependencies/`.
    +`ghidra.bin` must be a sibling of `ghidra`.
    +To respect the CDT project's resources, you will need to download the file using a browser, or at the very least, locate a suitable mirror on your own:
    +
    +```bash
    +cd ~/Downloads   # Or wherever
    +curl -OL http://$CHOOSE_YOUR_MIRROR/pub/eclipse/tools/cdt/releases/8.6/cdt-8.6.0.zip
    +mkdir -p ~/git/ghidra.bin/GhidraBuild/EclipsePlugins/GhidraDev/buildDependencies/
    +cp ~/Downloads/cdt-8.6.0.zip ~/git/ghidra.bin/GhidraBuild/EclipsePlugins/GhidraDev/buildDependencies/
    +```
    +
    +Download `PyDev 6.3.1.zip` from www.pydev.org, and place it in the same directory:
    +
    +```bash
    +cd ~/Downloads   # Or wherever
    +curl -OL https://sourceforge.net/projects/pydev/files/pydev/PyDev%206.3.1/PyDev%206.3.1.zip
    +cp ~/Downloads/'PyDev 6.3.1.zip' ~/git/ghidra.bin/GhidraBuild/EclipsePlugins/GhidraDev/buildDependencies/
    +```
    +
    +Use Gradle to unpack the dependencies for development and building.
    +First, you will need to uncomment the GhidraDev project in the ```settings.gradle``` file.
    +Then, from your clone:
    +
    +```bash
    +./gradlew cdtUnpack pyDevUnpack
    +```
    +
    +### Get Dependencies for GhidraServer
    +
    +Building the GhidraServer requires "Yet another Java service wrapper" (yajsw) version 12.12.
    +Note that building the full Ghidra package requires building the GhidraServer.
    +Download `yajsw-stable-12.12.zip` from their project on www.sourceforge.net, and place it in a directory named:
    +`ghidra.bin/Ghidra/Features/GhidraSerer/`:
    +
    +```bash
    +cd ~/Downloads   # Or wherever
    +curl -OL https://sourceforge.net/projects/yajsw/files/yajsw/yajsw-stable-12.12/yajsw-stable-12.12.zip
    +mkdir -p ~/git/ghidra.bin/Ghidra/Features/GhidraServer/
    +cp ~/Downloads/yajsw-stable-12.12.zip ~/git/ghidra.bin/Ghidra/Features/GhidraServer/
    +```
    +
    +Use Gradle to unpack the wrapper for development.
    +From your clone:
    +
    +```bash
    +./gradlew yajswDevUnpack
    +```
    +
    +# Build the full Ghidra package
    +
    +If you've followed all of the steps above, except perhaps importing to Eclipse, you should be able to produce a build.
    +Before building, you may want to update the version and release name.
    +These properties are kept in `Ghidra/application.properties`.
    +
    +If you want it included, you must also build the GhidraDevPlugin module first.
    +We do not yet have instructions for building the GhidraDevPlugin.
    +It should be relatively straightforward for anyone familiar with Eclipse PDE.
    +
    +To build the full package, use Gradle:
    +
    +```bash
    +./gradlew buildGhidra
    +```
    +
    +The output will be placed in `build/dist/`.
    +It will be named according to the version, release name, build date, and platform.
    +To test it, unzip it where you like, and execute `./ghidraRun`.
    +
    +# Building Supporting Data
    +
    +Some features of Ghidra require the curation of rather extensive data bases.
    +These include the Data Type Archives and Function ID Databases, both of which require collecting header files and libraries for the relevant SDKs and platforms.
    +Much of this work is done by hand, and the results are simply copied into the build.
    +We intend to document these procedures as soon as we can.
    +In the meantime, those artifacts can always be extracted from our binary release.
    +
    +## Building Data Type Archives
    +
    +TODO
    +
    +## Building FID Databases
    +
    +TODO
    
  • Ghidra/Configurations/Public_Release/build.gradle+2 0 added
  • Ghidra/Configurations/Public_Release/certification.manifest+32 0 added
  • Ghidra/Configurations/Public_Release/data/PDB_SYMBOL_SERVER_URLS.pdburl+1 0 added
  • Ghidra/Configurations/Public_Release/Module.manifest+0 0 added
  • Ghidra/Configurations/Public_Release/src/global/docs/ChangeHistory.html+80 0 added
  • Ghidra/Configurations/Public_Release/src/global/docs/languages/html/additionalpcode.html+323 0 added
  • Ghidra/Configurations/Public_Release/src/global/docs/languages/html/Diagram1.png+0 0 added
  • Ghidra/Configurations/Public_Release/src/global/docs/languages/html/Diagram2.png+0 0 added
  • Ghidra/Configurations/Public_Release/src/global/docs/languages/html/Diagram3.png+0 0 added
  • Ghidra/Configurations/Public_Release/src/global/docs/languages/html/Frontpage.css+51 0 added
  • Ghidra/Configurations/Public_Release/src/global/docs/languages/html/languages.css+26 0 added
  • Ghidra/Configurations/Public_Release/src/global/docs/languages/html/pcodedescription.html+2953 0 added
  • Ghidra/Configurations/Public_Release/src/global/docs/languages/html/pcoderef.html+363 0 added
  • Ghidra/Configurations/Public_Release/src/global/docs/languages/html/pseudo-ops.html+241 0 added
  • Ghidra/Configurations/Public_Release/src/global/docs/languages/html/reference.html+510 0 added
  • Ghidra/Configurations/Public_Release/src/global/docs/languages/html/sleigh_constructors.html+2278 0 added
  • Ghidra/Configurations/Public_Release/src/global/docs/languages/html/sleigh_context.html+363 0 added
  • Ghidra/Configurations/Public_Release/src/global/docs/languages/html/sleigh_definitions.html+353 0 added
  • Ghidra/Configurations/Public_Release/src/global/docs/languages/html/sleigh.html+438 0 added
  • Ghidra/Configurations/Public_Release/src/global/docs/languages/html/sleigh_layout.html+122 0 added
  • Ghidra/Configurations/Public_Release/src/global/docs/languages/html/sleigh_preprocessing.html+214 0 added
  • Ghidra/Configurations/Public_Release/src/global/docs/languages/html/sleigh_ref.html+595 0 added
  • Ghidra/Configurations/Public_Release/src/global/docs/languages/html/sleigh_symbols.html+224 0 added
  • Ghidra/Configurations/Public_Release/src/global/docs/languages/html/sleigh_tokens.html+271 0 added
  • Ghidra/Configurations/Public_Release/src/global/docs/languages/index.html+29 0 added
  • Ghidra/Configurations/Public_Release/src/global/docs/languages/manual_index.txt+54 0 added
  • Ghidra/Configurations/Public_Release/src/global/docs/languages/versioning.html+231 0 added
  • Ghidra/Configurations/Public_Release/src/global/docs/UserAgreement.html+20 0 added
  • Ghidra/Configurations/Public_Release/src/global/docs/WhatsNew.html+53 0 added
  • Ghidra/Configurations/Public_Release/src/main/resources/defaultTools/CodeBrowser.tool+459 0 added
  • Ghidra/Configurations/Public_Release/src/main/resources/splash.txt+15 0 added
  • Ghidra/Configurations/Public_Release/src/main/resources/UserAgreement.html+20 0 added
  • Ghidra/Extensions/sample/build.gradle+10 0 added
  • Ghidra/Extensions/sample/certification.manifest+24 0 added
  • Ghidra/Extensions/sample/data/README.txt+1 0 added
  • Ghidra/Extensions/sample/extension.properties+5 0 added
  • Ghidra/Extensions/sample/Module.manifest+0 0 added
  • Ghidra/Extensions/sample/src/main/help/help/shared/arrow.gif+0 0 added
  • Ghidra/Extensions/sample/src/main/help/help/shared/close16.gif+0 0 added
  • Ghidra/Extensions/sample/src/main/help/help/shared/Frontpage.css+58 0 added
  • Ghidra/Extensions/sample/src/main/help/help/shared/menu16.gif+0 0 added
  • Ghidra/Extensions/sample/src/main/help/help/shared/note.png+0 0 added
  • Ghidra/Extensions/sample/src/main/help/help/shared/note-red.png+0 0 added
  • Ghidra/Extensions/sample/src/main/help/help/shared/note.yellow.png+0 0 added
  • Ghidra/Extensions/sample/src/main/help/help/shared/redo.png+0 0 added
  • Ghidra/Extensions/sample/src/main/help/help/shared/tip.png+0 0 added
  • Ghidra/Extensions/sample/src/main/help/help/shared/undo.png+0 0 added
  • Ghidra/Extensions/sample/src/main/help/help/shared/warning.png+0 0 added
  • Ghidra/Extensions/sample/src/main/help/help/TOC_Source.xml+53 0 added
  • Ghidra/Extensions/sample/src/main/help/help/topics/SampleHelpTopic/SampleHelpFile.htm+78 0 added
  • Ghidra/Extensions/sample/src/main/java/ghidra/examples/EntropyFieldFactory.java+160 0 added
  • Ghidra/Extensions/sample/src/main/java/ghidra/examples/EntropyFieldLocation.java+46 0 added
  • Ghidra/Extensions/sample/src/main/java/ghidra/examples/graph/layout/SampleGraphJungLayout.java+44 0 added
  • Ghidra/Extensions/sample/src/main/java/ghidra/examples/graph/layout/SampleGraphJungLayoutProvider.java+39 0 added
  • Ghidra/Extensions/sample/src/main/java/ghidra/examples/graph/layout/SampleGraphLayout.java+44 0 added
  • Ghidra/Extensions/sample/src/main/java/ghidra/examples/graph/layout/SampleGraphLayoutProvider.java+57 0 added
  • Ghidra/Extensions/sample/src/main/java/ghidra/examples/graph/layout/SampleGraphPluginDependencyLayout.java+155 0 added
  • Ghidra/Extensions/sample/src/main/java/ghidra/examples/graph/layout/SampleGraphPluginDependencyLayoutProvider.java+55 0 added
  • Ghidra/Extensions/sample/src/main/java/ghidra/examples/graph/SampleEdge.java+35 0 added
  • Ghidra/Extensions/sample/src/main/java/ghidra/examples/graph/SampleGraph.java+51 0 added
  • Ghidra/Extensions/sample/src/main/java/ghidra/examples/graph/SampleGraphPlugin.java+83 0 added
  • Ghidra/Extensions/sample/src/main/java/ghidra/examples/graph/SampleGraphProvider.java+422 0 added
  • Ghidra/Extensions/sample/src/main/java/ghidra/examples/graph/SampleVertex.java+28 0 added
  • Ghidra/Extensions/sample/src/main/java/ghidra/examples/HelloProgramPlugin.java+125 0 added
  • Ghidra/Extensions/sample/src/main/java/ghidra/examples/HelloWorldComponentPlugin.java+55 0 added
  • Ghidra/Extensions/sample/src/main/java/ghidra/examples/HelloWorldComponentProvider.java+163 0 added
  • Ghidra/Extensions/sample/src/main/java/ghidra/examples/HelloWorldPlugin.java+68 0 added
  • Ghidra/Extensions/sample/src/main/java/ghidra/examples/HelloWorldService.java+23 0 added
  • Ghidra/Extensions/sample/src/main/java/ghidra/examples/KitchenSinkPlugin.java+173 0 added
  • Ghidra/Extensions/sample/src/main/java/ghidra/examples/SampleProgramTreePlugin.java+218 0 added
  • Ghidra/Extensions/sample/src/main/java/ghidra/examples/SampleStringTranslationPlugin.java+95 0 added
  • Ghidra/Extensions/sample/src/main/java/ghidra/examples/ShowInfoComponentProvider.java+122 0 added
  • Ghidra/Extensions/sample/src/main/java/ghidra/examples/ShowInfoPlugin.java+59 0 added
  • Ghidra/Extensions/sample/src/main/java/ghidra/examples/Template.java+226 0 added
  • Ghidra/Extensions/sample/src/main/java/ghidra/examples/TemplateProgramPlugin.java+157 0 added
  • Ghidra/Extensions/sample/src/main/resources/images/applications-development.png+0 0 added
  • Ghidra/Extensions/sample/src/main/resources/images/erase16.png+0 0 added
  • Ghidra/Extensions/sample/src/main/resources/images/information.png+0 0 added
  • Ghidra/Extensions/sample/src/test/java/ghidra/examples/HelloTest.java+27 0 added
  • Ghidra/Extensions/sample/src/test.slow/java/ghidra/examples/graph/SampleGraphPluginTest.java+186 0 added
  • Ghidra/Extensions/SampleTablePlugin/build.gradle+10 0 added
  • Ghidra/Extensions/SampleTablePlugin/certification.manifest+23 0 added
  • Ghidra/Extensions/SampleTablePlugin/data/ExtensionPoint.manifest+1 0 added
  • Ghidra/Extensions/SampleTablePlugin/extension.properties+5 0 added
  • Ghidra/Extensions/SampleTablePlugin/Module.manifest+0 0 added
  • Ghidra/Extensions/SampleTablePlugin/src/main/help/help/shared/arrow.gif+0 0 added
  • Ghidra/Extensions/SampleTablePlugin/src/main/help/help/shared/close16.gif+0 0 added
  • Ghidra/Extensions/SampleTablePlugin/src/main/help/help/shared/Frontpage.css+58 0 added
  • Ghidra/Extensions/SampleTablePlugin/src/main/help/help/shared/menu16.gif+0 0 added
  • Ghidra/Extensions/SampleTablePlugin/src/main/help/help/shared/note.png+0 0 added
  • Ghidra/Extensions/SampleTablePlugin/src/main/help/help/shared/note-red.png+0 0 added
  • Ghidra/Extensions/SampleTablePlugin/src/main/help/help/shared/note.yellow.png+0 0 added
  • Ghidra/Extensions/SampleTablePlugin/src/main/help/help/shared/redo.png+0 0 added
  • Ghidra/Extensions/SampleTablePlugin/src/main/help/help/shared/tip.png+0 0 added
  • Ghidra/Extensions/SampleTablePlugin/src/main/help/help/shared/undo.png+0 0 added
  • Ghidra/Extensions/SampleTablePlugin/src/main/help/help/shared/warning.png+0 0 added
  • Ghidra/Extensions/SampleTablePlugin/src/main/help/help/TOC_Source.xml+53 0 added
  • Ghidra/Extensions/SampleTablePlugin/src/main/help/help/topics/SampleHelpTopic/SampleHelpFile.htm+58 0 added
  • Ghidra/Extensions/SampleTablePlugin/src/main/java/ghidra/examples2/SampleSearcher.java+53 0 added
  • Ghidra/Extensions/SampleTablePlugin/src/main/java/ghidra/examples2/SampleSearchTableModel.java+88 0 added
  • Ghidra/Extensions/SampleTablePlugin/src/main/java/ghidra/examples2/SampleSearchTablePlugin.java+76 0 added
  • Ghidra/Extensions/SampleTablePlugin/src/main/java/ghidra/examples2/SampleSearchTableProvider.java+83 0 added
  • Ghidra/Extensions/SampleTablePlugin/src/main/java/ghidra/examples2/SearchResults.java+40 0 added
  • Ghidra/Extensions/SampleTablePlugin/src/main/java/ghidra/examples/BasicBlockCounterFunctionAlgorithm.java+64 0 added
  • Ghidra/Extensions/SampleTablePlugin/src/main/java/ghidra/examples/FunctionAlgorithm.java+30 0 added
  • Ghidra/Extensions/SampleTablePlugin/src/main/java/ghidra/examples/FunctionStatsRowObject.java+50 0 added
  • Ghidra/Extensions/SampleTablePlugin/src/main/java/ghidra/examples/ReferenceFunctionAlgorithm.java+63 0 added
  • Ghidra/Extensions/SampleTablePlugin/src/main/java/ghidra/examples/SampleTableModel.java+142 0 added
  • Ghidra/Extensions/SampleTablePlugin/src/main/java/ghidra/examples/SampleTablePlugin.java+84 0 added
  • Ghidra/Extensions/SampleTablePlugin/src/main/java/ghidra/examples/SampleTableProvider.java+247 0 added
  • Ghidra/Extensions/SampleTablePlugin/src/main/java/ghidra/examples/SizeFunctionAlgorithm.java+35 0 added
  • Ghidra/Extensions/SampleTablePlugin/src/main/resources/images/erase16.png+0 0 added
  • Ghidra/Extensions/SampleTablePlugin/src/main/resources/images/information.png+0 0 added
  • Ghidra/Features/Base/build.gradle+153 0 added
  • Ghidra/Features/Base/certification.manifest+1221 0 added
  • Ghidra/Features/Base/data/ElfFunctionsThatDoNotReturn+23 0 added
  • Ghidra/Features/Base/data/ExtensionPoint.manifest+21 0 added
  • Ghidra/Features/Base/data/file_extension_icons.xml+43 0 added
  • Ghidra/Features/Base/data/formats/clamp.properties+5 0 added
  • Ghidra/Features/Base/data/functionTags.xml+40 0 added
  • Ghidra/Features/Base/data/MachOFunctionsThatDoNotReturn+33 0 added
  • Ghidra/Features/Base/data/ms_pe_rich_products.xml+169 0 added
  • Ghidra/Features/Base/data/noReturnFunctionConstraints.xml+11 0 added
  • Ghidra/Features/Base/data/parserprofiles/clib.prf+90 0 added
  • Ghidra/Features/Base/data/parserprofiles/generic_clib_32.prf+241 0 added
  • Ghidra/Features/Base/data/parserprofiles/generic_clib_64.prf+241 0 added
  • Ghidra/Features/Base/data/parserprofiles/linux_32.prf+538 0 added
  • Ghidra/Features/Base/data/parserprofiles/linux_64.prf+537 0 added
  • Ghidra/Features/Base/data/parserprofiles/MacOSX_10.5.prf+214 0 added
  • Ghidra/Features/Base/data/parserprofiles/MacOSX_10.9.prf+335 0 added
  • Ghidra/Features/Base/data/parserprofiles/MacOSX_Cocoa.prf+36 0 added
  • Ghidra/Features/Base/data/parserprofiles/objc_mac_carbon.prf+383 0 added
  • Ghidra/Features/Base/data/parserprofiles/VisualStudio12_32.prf+207 0 added
  • Ghidra/Features/Base/data/parserprofiles/VisualStudio12_64.prf+210 0 added
  • Ghidra/Features/Base/data/parserprofiles/VisualStudio9.prf+89 0 added
  • Ghidra/Features/Base/data/parserprofiles/vs12Local.prf+252 0 added
  • Ghidra/Features/Base/data/PEFunctionsThatDoNotReturn+6 0 added
  • Ghidra/Features/Base/data/stringngrams/StringModel.sng+60243 0 added
  • Ghidra/Features/Base/data/symbols/win32/kernel32.hints+6 0 added
  • Ghidra/Features/Base/data/symbols/win32/mfc100.exports+13726 0 added
  • Ghidra/Features/Base/data/symbols/win32/mfc100u.exports+13811 0 added
  • Ghidra/Features/Base/data/symbols/win32/mfc110.exports+14204 0 added
  • Ghidra/Features/Base/data/symbols/win32/mfc110u.exports+14290 0 added
  • Ghidra/Features/Base/data/symbols/win32/mfc140.exports+14399 0 added
  • Ghidra/Features/Base/data/symbols/win32/mfc140u.exports+14485 0 added
  • Ghidra/Features/Base/data/symbols/win32/mfc42.exports+6399 0 added
  • Ghidra/Features/Base/data/symbols/win32/mfc42u.exports+6395 0 added
  • Ghidra/Features/Base/data/symbols/win32/mfc80.exports+6506 0 added
  • Ghidra/Features/Base/data/symbols/win32/mfc80u.exports+6505 0 added
  • Ghidra/Features/Base/data/symbols/win32/mfc90.exports+6570 0 added
  • Ghidra/Features/Base/data/symbols/win32/mfc90u.exports+6590 0 added
  • Ghidra/Features/Base/data/symbols/win32/msvcrt.hints+7 0 added
  • Ghidra/Features/Base/data/symbols/win64/kernel32.hints+6 0 added
  • Ghidra/Features/Base/data/symbols/win64/mfc100.exports+13351 0 added
  • Ghidra/Features/Base/data/symbols/win64/mfc100u.exports+13432 0 added
  • Ghidra/Features/Base/data/symbols/win64/mfc110.exports+13830 0 added
  • Ghidra/Features/Base/data/symbols/win64/mfc110u.exports+13911 0 added
  • Ghidra/Features/Base/data/symbols/win64/mfc140.exports+14026 0 added
  • Ghidra/Features/Base/data/symbols/win64/mfc140u.exports+14106 0 added
  • Ghidra/Features/Base/data/symbols/win64/mfc42.exports+6630 0 added
  • Ghidra/Features/Base/data/symbols/win64/mfc42u.exports+6626 0 added
  • Ghidra/Features/Base/data/symbols/win64/mfc80.exports+6132 0 added
  • Ghidra/Features/Base/data/symbols/win64/mfc80u.exports+6126 0 added
  • Ghidra/Features/Base/data/symbols/win64/mfc90.exports+6195 0 added
  • Ghidra/Features/Base/data/symbols/win64/mfc90u.exports+6210 0 added
  • Ghidra/Features/Base/data/symbols/win64/msvcrt.hints+7 0 added
  • Ghidra/Features/Base/data/typeinfo/generic/generic_clib_64.gdt+0 0 added
  • Ghidra/Features/Base/data/typeinfo/generic/generic_clib.gdt+0 0 added
  • Ghidra/Features/Base/data/typeinfo/mac_10.9/mac_osx.gdt+0 0 added
  • Ghidra/Features/Base/data/typeinfo/win32/msvcrt/clsids.txt+385 0 added
  • Ghidra/Features/Base/data/typeinfo/win32/msvcrt/guids.txt+662 0 added
  • Ghidra/Features/Base/data/typeinfo/win32/msvcrt/iids.txt+1124 0 added
  • Ghidra/Features/Base/data/typeinfo/win32/msvcrt/syntaxes.txt+1 0 added
  • Ghidra/Features/Base/data/typeinfo/win32/windows_vs12_32.gdt+0 0 added
  • Ghidra/Features/Base/data/typeinfo/win32/windows_vs12_64.gdt+0 0 added
  • Ghidra/Features/Base/developer_scripts/ApplyRTTITestScript.java+81 0 added
  • Ghidra/Features/Base/developer_scripts/BuildResultState.java+283 0 added
  • Ghidra/Features/Base/developer_scripts/CleanupMergeDatabasesScript.java+147 0 added
  • Ghidra/Features/Base/developer_scripts/ConsistencyCheck.java+104 0 added
  • Ghidra/Features/Base/developer_scripts/DumpGhidraCapabilitiesScript.java+111 0 added
  • Ghidra/Features/Base/.gitignore+2 0 added
  • Ghidra/Features/Base/.launch/Ghidra.launch+28 0 added
  • Ghidra/Features/Base/Module.manifest+1 0 added
  • Ghidra/.gitattributes+2 0 added
  • Ghidra/.gitignore+5 0 added
  • .gitattributes+56 0 added
    @@ -0,0 +1,56 @@
    +# Set the default behavior, in case people don't have core.autocrlf set.
    +* text=auto
    +
    +# Explicitly declare text files you want to always be normalized and converted
    +# to native line endings on checkout.
    +*.java text
    +*.gradle text
    +*.manifest text
    +*.css text
    +*.htm text
    +*.html text
    +*.js text
    +*.json text
    +*.jsp text
    +*.jspf text
    +*.jspx text
    +*.properties text
    +*.sh text
    +*.tld text
    +*.txt text
    +*.tag text
    +*.xml text
    +*.c text
    +*.h text
    +*.cpp text
    +*.hh text
    +*.cc text
    +
    +# Declare files that will always have CRLF line endings on checkout.
    +*.sln text eol=crlf
    +*.vcproj text eol=crlf
    +*.vcxproj text eol=crlf
    +*.bat text eol=crlf
    +
    +# Denote all files that are truly binary and should not be modified.
    +*.png binary
    +*.jpg binary
    +*.class binary
    +*.dll binary
    +*.ear binary
    +*.gif binary
    +*.ico binary
    +*.jar binary
    +*.jpeg binary
    +*.so binary
    +*.war binary
    +*.pdf binary
    +*.exe binary
    +*.lib binary
    +*.sa binary
    +*.gz binary
    +*.gzf binary
    +*.tgz binary
    +*.tar binary
    +
    +
    
  • .gitignore+58 9 modified
    @@ -1,14 +1,63 @@
    -.gradle
    +*.class
    +Thumbs.db
    +.DS_Store
    +.svn
    +excludedFiles.txt
    +.classpath
    +.project
    +ghidra.repos.config
    +
    +/*/*/*/*/*/bin/
    +/*/*/*/*/*/build/
    +/*/*/*/*/bin/
    +/*/*/*/*/build/
    +/*/*/*/bin/
    +/*/*/*/build/
    +/*/*/bin/
    +/*/*/build/
    +/*/bin/
    +/*/build/
     /build/
    +/bin/
    +
    +**/dist
    +repositories/
    +*.sla
    +
    +# Misc files
    +*.setting
    +*.settings
    +*.directory
    +.gradle/
    +.settings/
    +
    +# File locks
    +*.ulock
    +*.lock
    +
    +# Gradle creates these per developer
    +**/vs/
    +
    +# Misc files produced while executing application
    +Ghidra/.ghidraSvrKeys
    +wrapper.log*
     
    -# Ignore Gradle GUI config
    -gradle-app.setting
    +# Ignore object files
    +*.o
    +*.obj
     
    -# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
    -!gradle-wrapper.jar
    +# Ignore MS Visual Studio artifcats
    +Release
    +#Debug
    +*.ncb
    +*.suo
    +*.aps
    +*.vcproj.*
     
    -# Cache of project
    -.gradletasknamecache
    +# Ignore UNIX backup files
    +*~
    +*.swp
     
    -# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898
    -# gradle/wrapper/gradle-wrapper.properties
    +# Ignore eclipse project files
    +.project
    +.classpath
    
  • GPL/build.gradle+76 0 added
  • GPL/CabExtract/build.gradle+69 0 added
    @@ -0,0 +1,69 @@
    +apply plugin: 'eclipse'
    +eclipse.project.name = 'GPL CabExtract'
    +
    +project.ext.cabextract = "cabextract-1.6"
    +
    +
    +/*********************************************************************************
    + * CabExtract extraction task
    + *
    + * Unpacks the cabextract tar file that's needed for the symbol server.  This
    + * is only unpacked for building the tool; once it's built, this unzipped 
    + * archive is removed.
    + *
    + * NOTE: Ant is used so that timestamps are properly preserved, failure to 
    + * do so can cause the aclocal utility to be required which may be missing!
    + *********************************************************************************/
    + task unpackCabExtract (type: Copy) {
    + 
    + 	doFirst {
    + 		delete file("build/${cabextract}")
    + 	}
    + 	
    + 	doLast {
    + 		// Force all unpacked files to have the same timestamp
    + 		ant.touch() {
    + 			fileset(dir: file("build/${cabextract}"))
    +	    }
    + 	}
    + 	
    +	from tarTree(file("data/${cabextract}.tar.gz"))
    +	into 'build'
    +	
    +	// Force the task to be executed every time by setting to false.
    +	// This is done since configure changes the contents for a platform
    +	outputs.upToDateWhen { false }
    + }
    +
    +/*********************************************************************************
    + * CabExtract platform specific tasks
    + *
    + * The cabextract tool requires that its 'configure' script is called before make.
    + *********************************************************************************/
    +['linux64', 'osx64'].each { platform ->
    +		
    +	def configureName = "${platform}CabExtractConfigure"
    +	def makeName = "${platform}CabExtractMake" // native Make task found automatically
    +	
    +	task (configureName, type: Exec) {
    +		group "private"
    +		workingDir "build/${cabextract}"
    +		executable "./configure"
    +		dependsOn unpackCabExtract
    +	}
    +	
    +	task (makeName, type: Exec) {
    +		group "private"
    +		workingDir "build/${cabextract}"
    +		executable "make"
    +		dependsOn configureName
    +		doLast {
    +			copy {
    +				from "build/${cabextract}/cabextract"
    +				into "build/os/${platform}"
    +			}
    +		}
    +	}
    +}
    +
    +
    
  • GPL/CabExtract/certification.manifest+8 0 added
    @@ -0,0 +1,8 @@
    +##VERSION: 2.0
    +##MODULE IP: GPL 3
    +##MODULE IP: Public Domain
    +.classpath||Public Domain||||END|
    +.project||Public Domain||||END|
    +Module.manifest||Public Domain||||END|
    +build.gradle||Public Domain||||END|
    +data/cabextract-1.6.tar.gz||GPL 3||||END|
    
  • GPL/CabExtract/data/cabextract-1.6.tar.gz+0 0 added
  • GPL/CabExtract/Module.manifest+2 0 added
    @@ -0,0 +1,2 @@
    +MODULE FILE LICENSE: os/linux64/cabextract GPL 3
    +MODULE FILE LICENSE: os/osx64/cabextract GPL 3
    
  • GPL/certification.local.manifest+5 0 added
  • GPL/DemanglerGnu/build.gradle+109 0 added
    @@ -0,0 +1,109 @@
    +apply plugin: 'eclipse'
    +eclipse.project.name = 'GPL DemanglerGnu'
    +
    +apply from: "../nativeBuildProperties.gradle"
    +
    +
    +/****************************************************************************
    + * Defines the platforms we have to support in Ghidra.  This model is used 
    + * for all native builds and should be extended by each module as-needed.
    + ****************************************************************************/
    +model {
    +
    +	// define the platforms that we support in ghidra
    +	platforms {
    +		win64 {
    +			architecture 'x86_64'
    +			operatingSystem 'windows'
    +		}
    +		linux64 {
    +			architecture 'x86_64'
    +			operatingSystem 'linux'
    +		}
    +		osx64 {
    +			architecture 'x86_64'
    +			operatingSystem 'osx'
    +		}
    +	}	
    +}
    +
    +
    +/**
    + * This project has some native 'c' code we need to include in the zip for licensing 
    + * and build reasons. So include them here, but we have to do something special: the 
    + * source is divided up into folders for makefiles, headers and .c files:
    + * 		/headers
    + * 		/c
    + * 		/build
    + *
    + * The contents of all these need to be merged into the same folder for distribution.  
    + * Hence the following 3 'from' clauses:
    + */
    +task zipBuildableSource(type:Zip) {
    +
    +	group 'private'
    +	description "Collects the source files needed to build this module."
    +	baseName project.name + "-src-for-build"
    +	extension 'zip'
    +			
    +	from (project.projectDir.toString() + "/src/demangler_gnu/c") {
    +		into "/src/demangler_gnu"
    +	}
    +	from (project.projectDir.toString() + "/src/demangler_gnu/headers") {
    +		into "/src/demangler_gnu"
    +	}
    +	from (project.projectDir.toString() + "/src/demangler_gnu/build") {
    +		into "/src/demangler_gnu"
    +	}
    +	from (project.projectDir.toString() + "/src/demangler_gnu/README.txt")
    +}
    +
    +model {
    +	components {
    +		demangler_gnu(NativeExecutableSpec) {
    +			targetPlatform "win64"
    +			targetPlatform "linux64"
    +			targetPlatform "osx64"
    +			sources {
    +				c {
    +					source {
    +						srcDir "src/demangler_gnu/c"
    +					}
    +					exportedHeaders {
    +						srcDir "src/demangler_gnu/headers"
    +					}
    +				}
    +			}
    +			
    +		}
    +	}
    +}
    +
    +model {
    +	binaries {
    +		all{ b ->
    +			if (toolChain in Gcc) {
    +				cCompiler.args "-DMAIN_CPLUS_DEM"
    +				cCompiler.args "-DHAVE_STDLIB_H"
    +				cCompiler.args "-DHAVE_STRING_H"
    +				if (targetPlatform.operatingSystem.linux) {
    +//					linker.args "-static"
    +				}
    +			}
    +			else if (toolChain in VisualCpp) {
    +				cCompiler.args "/D_CONSOLE"
    +				cCompiler.args "/DMAIN_CPLUS_DEM"
    +				cCompiler.args "-DHAVE_STDLIB_H"
    +				cCompiler.args "-DHAVE_STRING_H"
    +			}
    +			else if (toolChain in Clang) {
    +				cCompiler.args "-DMAIN_CPLUS_DEM"
    +				cCompiler.args "-DHAVE_STDLIB_H"
    +				cCompiler.args "-DHAVE_STRING_H"
    +				if (targetPlatform.operatingSystem.linux) {
    +//					linker.args "-static"
    +				}
    +			}
    +		}
    +	}
    +}
    
  • GPL/DemanglerGnu/certification.manifest+11 0 added
    @@ -0,0 +1,11 @@
    +##VERSION: 2.0
    +##MODULE IP: GPL 3
    +##MODULE IP: GPL 3 Linking Permitted
    +##MODULE IP: LGPL 2.1
    +##MODULE IP: LGPL 3.0
    +##MODULE IP: Public Domain
    +.classpath||GHIDRA||||END|
    +.project||Public Domain||||END|
    +Module.manifest||Public Domain||||END|
    +build.gradle||Public Domain||||END|
    +src/demangler_gnu/README.txt||Public Domain||||END|
    
  • GPL/DemanglerGnu/Module.manifest+3 0 added
    @@ -0,0 +1,3 @@
    +MODULE FILE LICENSE: os/linux64/demangler_gnu GPL 3
    +MODULE FILE LICENSE: os/osx64/demangler_gnu GPL 3
    +MODULE FILE LICENSE: os/win64/demangler_gnu.exe GPL 3
    \ No newline at end of file
    
  • GPL/DemanglerGnu/src/demangler_gnu/c/alloca.c+488 0 added
    @@ -0,0 +1,488 @@
    +/* ###
    + * IP: LGPL 2.1
    + * REVIEWED: YES
    + * NOTE: license is not in file, but in the directory from whence it came: binutils-2.24/libiberty/COPYING.LIB
    + */
    +/* alloca.c -- allocate automatically reclaimed memory
    +   (Mostly) portable public-domain implementation -- D A Gwyn
    +
    +   This implementation of the PWB library alloca function,
    +   which is used to allocate space off the run-time stack so
    +   that it is automatically reclaimed upon procedure exit,
    +   was inspired by discussions with J. Q. Johnson of Cornell.
    +   J.Otto Tennant <jot@cray.com> contributed the Cray support.
    +
    +   There are some preprocessor constants that can
    +   be defined when compiling for your specific system, for
    +   improved efficiency; however, the defaults should be okay.
    +
    +   The general concept of this implementation is to keep
    +   track of all alloca-allocated blocks, and reclaim any
    +   that are found to be deeper in the stack than the current
    +   invocation.  This heuristic does not reclaim storage as
    +   soon as it becomes invalid, but it will do so eventually.
    +
    +   As a special case, alloca(0) reclaims storage without
    +   allocating any.  It is a good idea to use alloca(0) in
    +   your main control loop, etc. to force garbage collection.  */
    +
    +/*
    +
    +@deftypefn Replacement void* alloca (size_t @var{size})
    +
    +This function allocates memory which will be automatically reclaimed
    +after the procedure exits.  The @libib{} implementation does not free
    +the memory immediately but will do so eventually during subsequent
    +calls to this function.  Memory is allocated using @code{xmalloc} under
    +normal circumstances.
    +
    +The header file @file{alloca-conf.h} can be used in conjunction with the
    +GNU Autoconf test @code{AC_FUNC_ALLOCA} to test for and properly make
    +available this function.  The @code{AC_FUNC_ALLOCA} test requires that
    +client code use a block of preprocessor code to be safe (see the Autoconf
    +manual for more); this header incorporates that logic and more, including
    +the possibility of a GCC built-in function.
    +
    +@end deftypefn
    +
    +*/
    +
    +#ifdef HAVE_CONFIG_H
    +#include <config.h>
    +#endif
    +
    +#include <libiberty.h>
    +
    +#ifdef HAVE_STRING_H
    +#include <string.h>
    +#endif
    +#ifdef HAVE_STDLIB_H
    +#include <stdlib.h>
    +#endif
    +
    +/* These variables are used by the ASTRDUP implementation that relies
    +   on C_alloca.  */
    +#ifdef __cplusplus
    +extern "C" {
    +#endif /* __cplusplus */
    +const char *libiberty_optr;
    +char *libiberty_nptr;
    +unsigned long libiberty_len;
    +#ifdef __cplusplus
    +}
    +#endif /* __cplusplus */
    +
    +/* If your stack is a linked list of frames, you have to
    +   provide an "address metric" ADDRESS_FUNCTION macro.  */
    +
    +#if defined (CRAY) && defined (CRAY_STACKSEG_END)
    +static long i00afunc ();
    +#define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg))
    +#else
    +#define ADDRESS_FUNCTION(arg) &(arg)
    +#endif
    +
    +#ifndef NULL
    +#define	NULL	0
    +#endif
    +
    +/* Define STACK_DIRECTION if you know the direction of stack
    +   growth for your system; otherwise it will be automatically
    +   deduced at run-time.
    +
    +   STACK_DIRECTION > 0 => grows toward higher addresses
    +   STACK_DIRECTION < 0 => grows toward lower addresses
    +   STACK_DIRECTION = 0 => direction of growth unknown  */
    +
    +#ifndef STACK_DIRECTION
    +#define	STACK_DIRECTION	0	/* Direction unknown.  */
    +#endif
    +
    +#if STACK_DIRECTION != 0
    +
    +#define	STACK_DIR	STACK_DIRECTION	/* Known at compile-time.  */
    +
    +#else /* STACK_DIRECTION == 0; need run-time code.  */
    +
    +static int stack_dir;		/* 1 or -1 once known.  */
    +#define	STACK_DIR	stack_dir
    +
    +static void
    +find_stack_direction (void)
    +{
    +  static char *addr = NULL;	/* Address of first `dummy', once known.  */
    +  auto char dummy;		/* To get stack address.  */
    +
    +  if (addr == NULL)
    +    {				/* Initial entry.  */
    +      addr = ADDRESS_FUNCTION (dummy);
    +
    +      find_stack_direction ();	/* Recurse once.  */
    +    }
    +  else
    +    {
    +      /* Second entry.  */
    +      if (ADDRESS_FUNCTION (dummy) > addr)
    +	stack_dir = 1;		/* Stack grew upward.  */
    +      else
    +	stack_dir = -1;		/* Stack grew downward.  */
    +    }
    +}
    +
    +#endif /* STACK_DIRECTION == 0 */
    +
    +/* An "alloca header" is used to:
    +   (a) chain together all alloca'ed blocks;
    +   (b) keep track of stack depth.
    +
    +   It is very important that sizeof(header) agree with malloc
    +   alignment chunk size.  The following default should work okay.  */
    +
    +#ifndef	ALIGN_SIZE
    +#define	ALIGN_SIZE	sizeof(double)
    +#endif
    +
    +typedef union hdr
    +{
    +  char align[ALIGN_SIZE];	/* To force sizeof(header).  */
    +  struct
    +    {
    +      union hdr *next;		/* For chaining headers.  */
    +      char *deep;		/* For stack depth measure.  */
    +    } h;
    +} header;
    +
    +static header *last_alloca_header = NULL;	/* -> last alloca header.  */
    +
    +/* Return a pointer to at least SIZE bytes of storage,
    +   which will be automatically reclaimed upon exit from
    +   the procedure that called alloca.  Originally, this space
    +   was supposed to be taken from the current stack frame of the
    +   caller, but that method cannot be made to work for some
    +   implementations of C, for example under Gould's UTX/32.  */
    +
    +/* @undocumented C_alloca */
    +
    +PTR
    +C_alloca (size_t size)
    +{
    +  auto char probe;		/* Probes stack depth: */
    +  register char *depth = ADDRESS_FUNCTION (probe);
    +
    +#if STACK_DIRECTION == 0
    +  if (STACK_DIR == 0)		/* Unknown growth direction.  */
    +    find_stack_direction ();
    +#endif
    +
    +  /* Reclaim garbage, defined as all alloca'd storage that
    +     was allocated from deeper in the stack than currently.  */
    +
    +  {
    +    register header *hp;	/* Traverses linked list.  */
    +
    +    for (hp = last_alloca_header; hp != NULL;)
    +      if ((STACK_DIR > 0 && hp->h.deep > depth)
    +	  || (STACK_DIR < 0 && hp->h.deep < depth))
    +	{
    +	  register header *np = hp->h.next;
    +
    +	  free ((PTR) hp);	/* Collect garbage.  */
    +
    +	  hp = np;		/* -> next header.  */
    +	}
    +      else
    +	break;			/* Rest are not deeper.  */
    +
    +    last_alloca_header = hp;	/* -> last valid storage.  */
    +  }
    +
    +  if (size == 0)
    +    return NULL;		/* No allocation required.  */
    +
    +  /* Allocate combined header + user data storage.  */
    +
    +  {
    +    register void *new_storage = XNEWVEC (char, sizeof (header) + size);
    +    /* Address of header.  */
    +
    +    if (new_storage == 0)
    +      abort();
    +
    +    ((header *) new_storage)->h.next = last_alloca_header;
    +    ((header *) new_storage)->h.deep = depth;
    +
    +    last_alloca_header = (header *) new_storage;
    +
    +    /* User storage begins just after header.  */
    +
    +    return (PTR) ((char *) new_storage + sizeof (header));
    +  }
    +}
    +
    +#if defined (CRAY) && defined (CRAY_STACKSEG_END)
    +
    +#ifdef DEBUG_I00AFUNC
    +#include <stdio.h>
    +#endif
    +
    +#ifndef CRAY_STACK
    +#define CRAY_STACK
    +#ifndef CRAY2
    +/* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */
    +struct stack_control_header
    +  {
    +    long shgrow:32;		/* Number of times stack has grown.  */
    +    long shaseg:32;		/* Size of increments to stack.  */
    +    long shhwm:32;		/* High water mark of stack.  */
    +    long shsize:32;		/* Current size of stack (all segments).  */
    +  };
    +
    +/* The stack segment linkage control information occurs at
    +   the high-address end of a stack segment.  (The stack
    +   grows from low addresses to high addresses.)  The initial
    +   part of the stack segment linkage control information is
    +   0200 (octal) words.  This provides for register storage
    +   for the routine which overflows the stack.  */
    +
    +struct stack_segment_linkage
    +  {
    +    long ss[0200];		/* 0200 overflow words.  */
    +    long sssize:32;		/* Number of words in this segment.  */
    +    long ssbase:32;		/* Offset to stack base.  */
    +    long:32;
    +    long sspseg:32;		/* Offset to linkage control of previous
    +				   segment of stack.  */
    +    long:32;
    +    long sstcpt:32;		/* Pointer to task common address block.  */
    +    long sscsnm;		/* Private control structure number for
    +				   microtasking.  */
    +    long ssusr1;		/* Reserved for user.  */
    +    long ssusr2;		/* Reserved for user.  */
    +    long sstpid;		/* Process ID for pid based multi-tasking.  */
    +    long ssgvup;		/* Pointer to multitasking thread giveup.  */
    +    long sscray[7];		/* Reserved for Cray Research.  */
    +    long ssa0;
    +    long ssa1;
    +    long ssa2;
    +    long ssa3;
    +    long ssa4;
    +    long ssa5;
    +    long ssa6;
    +    long ssa7;
    +    long sss0;
    +    long sss1;
    +    long sss2;
    +    long sss3;
    +    long sss4;
    +    long sss5;
    +    long sss6;
    +    long sss7;
    +  };
    +
    +#else /* CRAY2 */
    +/* The following structure defines the vector of words
    +   returned by the STKSTAT library routine.  */
    +struct stk_stat
    +  {
    +    long now;			/* Current total stack size.  */
    +    long maxc;			/* Amount of contiguous space which would
    +				   be required to satisfy the maximum
    +				   stack demand to date.  */
    +    long high_water;		/* Stack high-water mark.  */
    +    long overflows;		/* Number of stack overflow ($STKOFEN) calls.  */
    +    long hits;			/* Number of internal buffer hits.  */
    +    long extends;		/* Number of block extensions.  */
    +    long stko_mallocs;		/* Block allocations by $STKOFEN.  */
    +    long underflows;		/* Number of stack underflow calls ($STKRETN).  */
    +    long stko_free;		/* Number of deallocations by $STKRETN.  */
    +    long stkm_free;		/* Number of deallocations by $STKMRET.  */
    +    long segments;		/* Current number of stack segments.  */
    +    long maxs;			/* Maximum number of stack segments so far.  */
    +    long pad_size;		/* Stack pad size.  */
    +    long current_address;	/* Current stack segment address.  */
    +    long current_size;		/* Current stack segment size.  This
    +				   number is actually corrupted by STKSTAT to
    +				   include the fifteen word trailer area.  */
    +    long initial_address;	/* Address of initial segment.  */
    +    long initial_size;		/* Size of initial segment.  */
    +  };
    +
    +/* The following structure describes the data structure which trails
    +   any stack segment.  I think that the description in 'asdef' is
    +   out of date.  I only describe the parts that I am sure about.  */
    +
    +struct stk_trailer
    +  {
    +    long this_address;		/* Address of this block.  */
    +    long this_size;		/* Size of this block (does not include
    +				   this trailer).  */
    +    long unknown2;
    +    long unknown3;
    +    long link;			/* Address of trailer block of previous
    +				   segment.  */
    +    long unknown5;
    +    long unknown6;
    +    long unknown7;
    +    long unknown8;
    +    long unknown9;
    +    long unknown10;
    +    long unknown11;
    +    long unknown12;
    +    long unknown13;
    +    long unknown14;
    +  };
    +
    +#endif /* CRAY2 */
    +#endif /* not CRAY_STACK */
    +
    +#ifdef CRAY2
    +/* Determine a "stack measure" for an arbitrary ADDRESS.
    +   I doubt that "lint" will like this much.  */
    +
    +static long
    +i00afunc (long *address)
    +{
    +  struct stk_stat status;
    +  struct stk_trailer *trailer;
    +  long *block, size;
    +  long result = 0;
    +
    +  /* We want to iterate through all of the segments.  The first
    +     step is to get the stack status structure.  We could do this
    +     more quickly and more directly, perhaps, by referencing the
    +     $LM00 common block, but I know that this works.  */
    +
    +  STKSTAT (&status);
    +
    +  /* Set up the iteration.  */
    +
    +  trailer = (struct stk_trailer *) (status.current_address
    +				    + status.current_size
    +				    - 15);
    +
    +  /* There must be at least one stack segment.  Therefore it is
    +     a fatal error if "trailer" is null.  */
    +
    +  if (trailer == 0)
    +    abort ();
    +
    +  /* Discard segments that do not contain our argument address.  */
    +
    +  while (trailer != 0)
    +    {
    +      block = (long *) trailer->this_address;
    +      size = trailer->this_size;
    +      if (block == 0 || size == 0)
    +	abort ();
    +      trailer = (struct stk_trailer *) trailer->link;
    +      if ((block <= address) && (address < (block + size)))
    +	break;
    +    }
    +
    +  /* Set the result to the offset in this segment and add the sizes
    +     of all predecessor segments.  */
    +
    +  result = address - block;
    +
    +  if (trailer == 0)
    +    {
    +      return result;
    +    }
    +
    +  do
    +    {
    +      if (trailer->this_size <= 0)
    +	abort ();
    +      result += trailer->this_size;
    +      trailer = (struct stk_trailer *) trailer->link;
    +    }
    +  while (trailer != 0);
    +
    +  /* We are done.  Note that if you present a bogus address (one
    +     not in any segment), you will get a different number back, formed
    +     from subtracting the address of the first block.  This is probably
    +     not what you want.  */
    +
    +  return (result);
    +}
    +
    +#else /* not CRAY2 */
    +/* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP.
    +   Determine the number of the cell within the stack,
    +   given the address of the cell.  The purpose of this
    +   routine is to linearize, in some sense, stack addresses
    +   for alloca.  */
    +
    +static long
    +i00afunc (long address)
    +{
    +  long stkl = 0;
    +
    +  long size, pseg, this_segment, stack;
    +  long result = 0;
    +
    +  struct stack_segment_linkage *ssptr;
    +
    +  /* Register B67 contains the address of the end of the
    +     current stack segment.  If you (as a subprogram) store
    +     your registers on the stack and find that you are past
    +     the contents of B67, you have overflowed the segment.
    +
    +     B67 also points to the stack segment linkage control
    +     area, which is what we are really interested in.  */
    +
    +  stkl = CRAY_STACKSEG_END ();
    +  ssptr = (struct stack_segment_linkage *) stkl;
    +
    +  /* If one subtracts 'size' from the end of the segment,
    +     one has the address of the first word of the segment.
    +
    +     If this is not the first segment, 'pseg' will be
    +     nonzero.  */
    +
    +  pseg = ssptr->sspseg;
    +  size = ssptr->sssize;
    +
    +  this_segment = stkl - size;
    +
    +  /* It is possible that calling this routine itself caused
    +     a stack overflow.  Discard stack segments which do not
    +     contain the target address.  */
    +
    +  while (!(this_segment <= address && address <= stkl))
    +    {
    +#ifdef DEBUG_I00AFUNC
    +      fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl);
    +#endif
    +      if (pseg == 0)
    +	break;
    +      stkl = stkl - pseg;
    +      ssptr = (struct stack_segment_linkage *) stkl;
    +      size = ssptr->sssize;
    +      pseg = ssptr->sspseg;
    +      this_segment = stkl - size;
    +    }
    +
    +  result = address - this_segment;
    +
    +  /* If you subtract pseg from the current end of the stack,
    +     you get the address of the previous stack segment's end.
    +     This seems a little convoluted to me, but I'll bet you save
    +     a cycle somewhere.  */
    +
    +  while (pseg != 0)
    +    {
    +#ifdef DEBUG_I00AFUNC
    +      fprintf (stderr, "%011o %011o\n", pseg, size);
    +#endif
    +      stkl = stkl - pseg;
    +      ssptr = (struct stack_segment_linkage *) stkl;
    +      size = ssptr->sssize;
    +      pseg = ssptr->sspseg;
    +      result += size;
    +    }
    +  return (result);
    +}
    +
    +#endif /* not CRAY2 */
    +#endif /* CRAY */
    
  • GPL/DemanglerGnu/src/demangler_gnu/c/argv.c+545 0 added
    @@ -0,0 +1,545 @@
    +/* ###
    + * IP: LGPL 2.1
    + * REVIEWED: YES
    + * NOTE: from binutils 2.24
    + */
    +/* Create and destroy argument vectors (argv's)
    +   Copyright (C) 1992, 2001, 2010, 2012 Free Software Foundation, Inc.
    +   Written by Fred Fish @ Cygnus Support
    +
    +This file is part of the libiberty library.
    +Libiberty is free software; you can redistribute it and/or
    +modify it under the terms of the GNU Library General Public
    +License as published by the Free Software Foundation; either
    +version 2 of the License, or (at your option) any later version.
    +
    +Libiberty 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
    +Library General Public License for more details.
    +
    +You should have received a copy of the GNU Library General Public
    +License along with libiberty; see the file COPYING.LIB.  If
    +not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
    +Boston, MA 02110-1301, USA.  */
    +
    +
    +/*  Create and destroy argument vectors.  An argument vector is simply an
    +    array of string pointers, terminated by a NULL pointer. */
    +
    +#ifdef HAVE_CONFIG_H
    +#include "config.h"
    +#endif
    +#include "ansidecl.h"
    +#include "libiberty.h"
    +#include "safe-ctype.h"
    +
    +/*  Routines imported from standard C runtime libraries. */
    +
    +#include <stddef.h>
    +#include <string.h>
    +#include <stdlib.h>
    +#include <stdio.h>
    +
    +#ifndef NULL
    +#define NULL 0
    +#endif
    +
    +#ifndef EOS
    +#define EOS '\0'
    +#endif
    +
    +#define INITIAL_MAXARGC 8	/* Number of args + NULL in initial argv */
    +
    +
    +/*
    +
    +@deftypefn Extension char** dupargv (char **@var{vector})
    +
    +Duplicate an argument vector.  Simply scans through @var{vector},
    +duplicating each argument until the terminating @code{NULL} is found.
    +Returns a pointer to the argument vector if successful.  Returns
    +@code{NULL} if there is insufficient memory to complete building the
    +argument vector.
    +
    +@end deftypefn
    +
    +*/
    +
    +char **
    +dupargv (char **argv)
    +{
    +  int argc;
    +  char **copy;
    +  
    +  if (argv == NULL)
    +    return NULL;
    +  
    +  /* the vector */
    +  for (argc = 0; argv[argc] != NULL; argc++);
    +  copy = (char **) xmalloc ((argc + 1) * sizeof (char *));
    +
    +  /* the strings */
    +  for (argc = 0; argv[argc] != NULL; argc++)
    +    {
    +      int len = strlen (argv[argc]);
    +      copy[argc] = (char *) xmalloc (len + 1);
    +      strcpy (copy[argc], argv[argc]);
    +    }
    +  copy[argc] = NULL;
    +  return copy;
    +}
    +
    +/*
    +
    +@deftypefn Extension void freeargv (char **@var{vector})
    +
    +Free an argument vector that was built using @code{buildargv}.  Simply
    +scans through @var{vector}, freeing the memory for each argument until
    +the terminating @code{NULL} is found, and then frees @var{vector}
    +itself.
    +
    +@end deftypefn
    +
    +*/
    +
    +void freeargv (char **vector)
    +{
    +  register char **scan;
    +
    +  if (vector != NULL)
    +    {
    +      for (scan = vector; *scan != NULL; scan++)
    +	{
    +	  free (*scan);
    +	}
    +      free (vector);
    +    }
    +}
    +
    +static void
    +consume_whitespace (const char **input)
    +{
    +  while (ISSPACE (**input))
    +    {
    +      (*input)++;
    +    }
    +}
    +
    +static int
    +only_whitespace (const char* input)
    +{
    +  while (*input != EOS && ISSPACE (*input))
    +    input++;
    +
    +  return (*input == EOS);
    +}
    +
    +/*
    +
    +@deftypefn Extension char** buildargv (char *@var{sp})
    +
    +Given a pointer to a string, parse the string extracting fields
    +separated by whitespace and optionally enclosed within either single
    +or double quotes (which are stripped off), and build a vector of
    +pointers to copies of the string for each field.  The input string
    +remains unchanged.  The last element of the vector is followed by a
    +@code{NULL} element.
    +
    +All of the memory for the pointer array and copies of the string
    +is obtained from @code{xmalloc}.  All of the memory can be returned to the
    +system with the single function call @code{freeargv}, which takes the
    +returned result of @code{buildargv}, as it's argument.
    +
    +Returns a pointer to the argument vector if successful.  Returns
    +@code{NULL} if @var{sp} is @code{NULL} or if there is insufficient
    +memory to complete building the argument vector.
    +
    +If the input is a null string (as opposed to a @code{NULL} pointer),
    +then buildarg returns an argument vector that has one arg, a null
    +string.
    +
    +@end deftypefn
    +
    +The memory for the argv array is dynamically expanded as necessary.
    +
    +In order to provide a working buffer for extracting arguments into,
    +with appropriate stripping of quotes and translation of backslash
    +sequences, we allocate a working buffer at least as long as the input
    +string.  This ensures that we always have enough space in which to
    +work, since the extracted arg is never larger than the input string.
    +
    +The argument vector is always kept terminated with a @code{NULL} arg
    +pointer, so it can be passed to @code{freeargv} at any time, or
    +returned, as appropriate.
    +
    +*/
    +
    +char **buildargv (const char *input)
    +{
    +  char *arg;
    +  char *copybuf;
    +  int squote = 0;
    +  int dquote = 0;
    +  int bsquote = 0;
    +  int argc = 0;
    +  int maxargc = 0;
    +  char **argv = NULL;
    +  char **nargv;
    +
    +  if (input != NULL)
    +    {
    +      copybuf = (char *) xmalloc (strlen (input) + 1);
    +      /* Is a do{}while to always execute the loop once.  Always return an
    +	 argv, even for null strings.  See NOTES above, test case below. */
    +      do
    +	{
    +	  /* Pick off argv[argc] */
    +	  consume_whitespace (&input);
    +
    +	  if ((maxargc == 0) || (argc >= (maxargc - 1)))
    +	    {
    +	      /* argv needs initialization, or expansion */
    +	      if (argv == NULL)
    +		{
    +		  maxargc = INITIAL_MAXARGC;
    +		  nargv = (char **) xmalloc (maxargc * sizeof (char *));
    +		}
    +	      else
    +		{
    +		  maxargc *= 2;
    +		  nargv = (char **) xrealloc (argv, maxargc * sizeof (char *));
    +		}
    +	      argv = nargv;
    +	      argv[argc] = NULL;
    +	    }
    +	  /* Begin scanning arg */
    +	  arg = copybuf;
    +	  while (*input != EOS)
    +	    {
    +	      if (ISSPACE (*input) && !squote && !dquote && !bsquote)
    +		{
    +		  break;
    +		}
    +	      else
    +		{
    +		  if (bsquote)
    +		    {
    +		      bsquote = 0;
    +		      *arg++ = *input;
    +		    }
    +		  else if (*input == '\\')
    +		    {
    +		      bsquote = 1;
    +		    }
    +		  else if (squote)
    +		    {
    +		      if (*input == '\'')
    +			{
    +			  squote = 0;
    +			}
    +		      else
    +			{
    +			  *arg++ = *input;
    +			}
    +		    }
    +		  else if (dquote)
    +		    {
    +		      if (*input == '"')
    +			{
    +			  dquote = 0;
    +			}
    +		      else
    +			{
    +			  *arg++ = *input;
    +			}
    +		    }
    +		  else
    +		    {
    +		      if (*input == '\'')
    +			{
    +			  squote = 1;
    +			}
    +		      else if (*input == '"')
    +			{
    +			  dquote = 1;
    +			}
    +		      else
    +			{
    +			  *arg++ = *input;
    +			}
    +		    }
    +		  input++;
    +		}
    +	    }
    +	  *arg = EOS;
    +	  argv[argc] = xstrdup (copybuf);
    +	  argc++;
    +	  argv[argc] = NULL;
    +
    +	  consume_whitespace (&input);
    +	}
    +      while (*input != EOS);
    +
    +      free (copybuf);
    +    }
    +  return (argv);
    +}
    +
    +/*
    +
    +@deftypefn Extension int writeargv (const char **@var{argv}, FILE *@var{file})
    +
    +Write each member of ARGV, handling all necessary quoting, to the file
    +named by FILE, separated by whitespace.  Return 0 on success, non-zero
    +if an error occurred while writing to FILE.
    +
    +@end deftypefn
    +
    +*/
    +
    +int
    +writeargv (char **argv, FILE *f)
    +{
    +  int status = 0;
    +
    +  if (f == NULL)
    +    return 1;
    +
    +  while (*argv != NULL)
    +    {
    +      const char *arg = *argv;
    +
    +      while (*arg != EOS)
    +        {
    +          char c = *arg;
    +
    +          if (ISSPACE(c) || c == '\\' || c == '\'' || c == '"')
    +            if (EOF == fputc ('\\', f))
    +              {
    +                status = 1;
    +                goto done;
    +              }
    +
    +          if (EOF == fputc (c, f))
    +            {
    +              status = 1;
    +              goto done;
    +            }
    +          arg++;
    +        }
    +
    +      if (EOF == fputc ('\n', f))
    +        {
    +          status = 1;
    +          goto done;
    +        }
    +      argv++;
    +    }
    +
    + done:
    +  return status;
    +}
    +
    +/*
    +
    +@deftypefn Extension void expandargv (int *@var{argcp}, char ***@var{argvp})
    +
    +The @var{argcp} and @code{argvp} arguments are pointers to the usual
    +@code{argc} and @code{argv} arguments to @code{main}.  This function
    +looks for arguments that begin with the character @samp{@@}.  Any such
    +arguments are interpreted as ``response files''.  The contents of the
    +response file are interpreted as additional command line options.  In
    +particular, the file is separated into whitespace-separated strings;
    +each such string is taken as a command-line option.  The new options
    +are inserted in place of the option naming the response file, and
    +@code{*argcp} and @code{*argvp} will be updated.  If the value of
    +@code{*argvp} is modified by this function, then the new value has
    +been dynamically allocated and can be deallocated by the caller with
    +@code{freeargv}.  However, most callers will simply call
    +@code{expandargv} near the beginning of @code{main} and allow the
    +operating system to free the memory when the program exits.
    +
    +@end deftypefn
    +
    +*/
    +
    +void
    +expandargv (int *argcp, char ***argvp)
    +{
    +  /* The argument we are currently processing.  */
    +  int i = 0;
    +  /* Non-zero if ***argvp has been dynamically allocated.  */
    +  int argv_dynamic = 0;
    +  /* Limit the number of response files that we parse in order
    +     to prevent infinite recursion.  */
    +  unsigned int iteration_limit = 2000;
    +  /* Loop over the arguments, handling response files.  We always skip
    +     ARGVP[0], as that is the name of the program being run.  */
    +  while (++i < *argcp)
    +    {
    +      /* The name of the response file.  */
    +      const char *filename;
    +      /* The response file.  */
    +      FILE *f;
    +      /* An upper bound on the number of characters in the response
    +	 file.  */
    +      long pos;
    +      /* The number of characters in the response file, when actually
    +	 read.  */
    +      size_t len;
    +      /* A dynamically allocated buffer used to hold options read from a
    +	 response file.  */
    +      char *buffer;
    +      /* Dynamically allocated storage for the options read from the
    +	 response file.  */
    +      char **file_argv;
    +      /* The number of options read from the response file, if any.  */
    +      size_t file_argc;
    +      /* We are only interested in options of the form "@file".  */
    +      filename = (*argvp)[i];
    +      if (filename[0] != '@')
    +	continue;
    +      /* If we have iterated too many times then stop.  */
    +      if (-- iteration_limit == 0)
    +	{
    +	  fprintf (stderr, "%s: error: too many @-files encountered\n", (*argvp)[0]);
    +	  xexit (1);
    +	}
    +      /* Read the contents of the file.  */
    +      f = fopen (++filename, "r");
    +      if (!f)
    +	continue;
    +      if (fseek (f, 0L, SEEK_END) == -1)
    +	goto error;
    +      pos = ftell (f);
    +      if (pos == -1)
    +	goto error;
    +      if (fseek (f, 0L, SEEK_SET) == -1)
    +	goto error;
    +      buffer = (char *) xmalloc (pos * sizeof (char) + 1);
    +      len = fread (buffer, sizeof (char), pos, f);
    +      if (len != (size_t) pos
    +	  /* On Windows, fread may return a value smaller than POS,
    +	     due to CR/LF->CR translation when reading text files.
    +	     That does not in-and-of itself indicate failure.  */
    +	  && ferror (f))
    +	goto error;
    +      /* Add a NUL terminator.  */
    +      buffer[len] = '\0';
    +      /* If the file is empty or contains only whitespace, buildargv would
    +	 return a single empty argument.  In this context we want no arguments,
    +	 instead.  */
    +      if (only_whitespace (buffer))
    +	{
    +	  file_argv = (char **) xmalloc (sizeof (char *));
    +	  file_argv[0] = NULL;
    +	}
    +      else
    +	/* Parse the string.  */
    +	file_argv = buildargv (buffer);
    +      /* If *ARGVP is not already dynamically allocated, copy it.  */
    +      if (!argv_dynamic)
    +	*argvp = dupargv (*argvp);
    +      /* Count the number of arguments.  */
    +      file_argc = 0;
    +      while (file_argv[file_argc])
    +	++file_argc;
    +      /* Now, insert FILE_ARGV into ARGV.  The "+1" below handles the
    +	 NULL terminator at the end of ARGV.  */ 
    +      *argvp = ((char **) 
    +		xrealloc (*argvp, 
    +			  (*argcp + file_argc + 1) * sizeof (char *)));
    +      memmove (*argvp + i + file_argc, *argvp + i + 1, 
    +	       (*argcp - i) * sizeof (char *));
    +      memcpy (*argvp + i, file_argv, file_argc * sizeof (char *));
    +      /* The original option has been replaced by all the new
    +	 options.  */
    +      *argcp += file_argc - 1;
    +      /* Free up memory allocated to process the response file.  We do
    +	 not use freeargv because the individual options in FILE_ARGV
    +	 are now in the main ARGV.  */
    +      free (file_argv);
    +      free (buffer);
    +      /* Rescan all of the arguments just read to support response
    +	 files that include other response files.  */
    +      --i;
    +    error:
    +      /* We're all done with the file now.  */
    +      fclose (f);
    +    }
    +}
    +
    +/*
    +
    +@deftypefn Extension int countargv (char **@var{argv})
    +
    +Return the number of elements in @var{argv}.
    +Returns zero if @var{argv} is NULL.
    +
    +@end deftypefn
    +
    +*/
    +
    +int
    +countargv (char **argv)
    +{
    +  int argc;
    +
    +  if (argv == NULL)
    +    return 0;
    +  for (argc = 0; argv[argc] != NULL; argc++)
    +    continue;
    +  return argc;
    +}
    +
    +#ifdef MAIN
    +
    +/* Simple little test driver. */
    +
    +static const char *const tests[] =
    +{
    +  "a simple command line",
    +  "arg 'foo' is single quoted",
    +  "arg \"bar\" is double quoted",
    +  "arg \"foo bar\" has embedded whitespace",
    +  "arg 'Jack said \\'hi\\'' has single quotes",
    +  "arg 'Jack said \\\"hi\\\"' has double quotes",
    +  "a b c d e f g h i j k l m n o p q r s t u v w x y z 1 2 3 4 5 6 7 8 9",
    +  
    +  /* This should be expanded into only one argument.  */
    +  "trailing-whitespace ",
    +
    +  "",
    +  NULL
    +};
    +
    +int
    +main (void)
    +{
    +  char **argv;
    +  const char *const *test;
    +  char **targs;
    +
    +  for (test = tests; *test != NULL; test++)
    +    {
    +      printf ("buildargv(\"%s\")\n", *test);
    +      if ((argv = buildargv (*test)) == NULL)
    +	{
    +	  printf ("failed!\n\n");
    +	}
    +      else
    +	{
    +	  for (targs = argv; *targs != NULL; targs++)
    +	    {
    +	      printf ("\t\"%s\"\n", *targs);
    +	    }
    +	  printf ("\n");
    +	}
    +      freeargv (argv);
    +    }
    +
    +  return 0;
    +}
    +
    +#endif	/* MAIN */
    
  • GPL/DemanglerGnu/src/demangler_gnu/c/cp-demangle.c+5948 0 added
  • GPL/DemanglerGnu/src/demangler_gnu/c/cplus-dem.c+5282 0 added
  • GPL/DemanglerGnu/src/demangler_gnu/c/dyn-string.c+401 0 added
    @@ -0,0 +1,401 @@
    +/* ###
    + * IP: GPL 3 Linking Permitted
    + * REVIEWED: YES
    + */
    +/* An abstract string datatype.
    +   Copyright (C) 1998, 1999, 2000, 2002, 2004 Free Software Foundation, Inc.
    +   Contributed by Mark Mitchell (mark@markmitchell.com).
    +
    +This file is part of GNU CC.
    +   
    +GNU CC 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, or (at your option)
    +any later version.
    +
    +In addition to the permissions in the GNU General Public License, the
    +Free Software Foundation gives you unlimited permission to link the
    +compiled version of this file into combinations with other programs,
    +and to distribute those combinations without any restriction coming
    +from the use of this file.  (The General Public License restrictions
    +do apply in other respects; for example, they cover modification of
    +the file, and distribution when not linked into a combined
    +executable.)
    +
    +GNU CC 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 GNU CC; see the file COPYING.  If not, write to
    +the Free Software Foundation, 51 Franklin Street - Fifth Floor,
    +Boston, MA 02110-1301, USA.  */
    +
    +#ifdef HAVE_CONFIG_H
    +#include "config.h"
    +#endif
    +
    +#include <stdio.h>
    +
    +#ifdef HAVE_STRING_H
    +#include <string.h>
    +#endif
    +
    +#ifdef HAVE_STDLIB_H
    +#include <stdlib.h>
    +#endif
    +
    +#include "libiberty.h"
    +#include "dyn-string.h"
    +
    +/* Performs in-place initialization of a dyn_string struct.  This
    +   function can be used with a dyn_string struct on the stack or
    +   embedded in another object.  The contents of of the string itself
    +   are still dynamically allocated.  The string initially is capable
    +   of holding at least SPACE characeters, including the terminating
    +   NUL.  If SPACE is 0, it will silently be increated to 1.  
    +
    +   If RETURN_ON_ALLOCATION_FAILURE is defined and memory allocation
    +   fails, returns 0.  Otherwise returns 1.  */
    +
    +int
    +dyn_string_init (struct dyn_string *ds_struct_ptr, int space)
    +{
    +  /* We need at least one byte in which to store the terminating NUL.  */
    +  if (space == 0)
    +    space = 1;
    +
    +#ifdef RETURN_ON_ALLOCATION_FAILURE
    +  ds_struct_ptr->s = (char *) malloc (space);
    +  if (ds_struct_ptr->s == NULL)
    +    return 0;
    +#else
    +  ds_struct_ptr->s = XNEWVEC (char, space);
    +#endif
    +  ds_struct_ptr->allocated = space;
    +  ds_struct_ptr->length = 0;
    +  ds_struct_ptr->s[0] = '\0';
    +
    +  return 1;
    +}
    +
    +/* Create a new dynamic string capable of holding at least SPACE
    +   characters, including the terminating NUL.  If SPACE is 0, it will
    +   be silently increased to 1.  If RETURN_ON_ALLOCATION_FAILURE is
    +   defined and memory allocation fails, returns NULL.  Otherwise
    +   returns the newly allocated string.  */
    +
    +dyn_string_t 
    +dyn_string_new (int space)
    +{
    +  dyn_string_t result;
    +#ifdef RETURN_ON_ALLOCATION_FAILURE
    +  result = (dyn_string_t) malloc (sizeof (struct dyn_string));
    +  if (result == NULL)
    +    return NULL;
    +  if (!dyn_string_init (result, space))
    +    {
    +      free (result);
    +      return NULL;
    +    }
    +#else
    +  result = XNEW (struct dyn_string);
    +  dyn_string_init (result, space);
    +#endif
    +  return result;
    +}
    +
    +/* Free the memory used by DS.  */
    +
    +void 
    +dyn_string_delete (dyn_string_t ds)
    +{
    +  free (ds->s);
    +  free (ds);
    +}
    +
    +/* Returns the contents of DS in a buffer allocated with malloc.  It
    +   is the caller's responsibility to deallocate the buffer using free.
    +   DS is then set to the empty string.  Deletes DS itself.  */
    +
    +char*
    +dyn_string_release (dyn_string_t ds)
    +{
    +  /* Store the old buffer.  */
    +  char* result = ds->s;
    +  /* The buffer is no longer owned by DS.  */
    +  ds->s = NULL;
    +  /* Delete DS.  */
    +  free (ds);
    +  /* Return the old buffer.  */
    +  return result;
    +}
    +
    +/* Increase the capacity of DS so it can hold at least SPACE
    +   characters, plus the terminating NUL.  This function will not (at
    +   present) reduce the capacity of DS.  Returns DS on success. 
    +
    +   If RETURN_ON_ALLOCATION_FAILURE is defined and a memory allocation
    +   operation fails, deletes DS and returns NULL.  */
    +
    +dyn_string_t 
    +dyn_string_resize (dyn_string_t ds, int space)
    +{
    +  int new_allocated = ds->allocated;
    +
    +  /* Increase SPACE to hold the NUL termination.  */
    +  ++space;
    +
    +  /* Increase allocation by factors of two.  */
    +  while (space > new_allocated)
    +    new_allocated *= 2;
    +    
    +  if (new_allocated != ds->allocated)
    +    {
    +      ds->allocated = new_allocated;
    +      /* We actually need more space.  */
    +#ifdef RETURN_ON_ALLOCATION_FAILURE
    +      ds->s = (char *) realloc (ds->s, ds->allocated);
    +      if (ds->s == NULL)
    +	{
    +	  free (ds);
    +	  return NULL;
    +	}
    +#else
    +      ds->s = XRESIZEVEC (char, ds->s, ds->allocated);
    +#endif
    +    }
    +
    +  return ds;
    +}
    +
    +/* Sets the contents of DS to the empty string.  */
    +
    +void
    +dyn_string_clear (dyn_string_t ds)
    +{
    +  /* A dyn_string always has room for at least the NUL terminator.  */
    +  ds->s[0] = '\0';
    +  ds->length = 0;
    +}
    +
    +/* Makes the contents of DEST the same as the contents of SRC.  DEST
    +   and SRC must be distinct.  Returns 1 on success.  On failure, if
    +   RETURN_ON_ALLOCATION_FAILURE, deletes DEST and returns 0.  */
    +
    +int
    +dyn_string_copy (dyn_string_t dest, dyn_string_t src)
    +{
    +  if (dest == src)
    +    abort ();
    +
    +  /* Make room in DEST.  */
    +  if (dyn_string_resize (dest, src->length) == NULL)
    +    return 0;
    +  /* Copy DEST into SRC.  */
    +  strcpy (dest->s, src->s);
    +  /* Update the size of DEST.  */
    +  dest->length = src->length;
    +  return 1;
    +}
    +
    +/* Copies SRC, a NUL-terminated string, into DEST.  Returns 1 on
    +   success.  On failure, if RETURN_ON_ALLOCATION_FAILURE, deletes DEST
    +   and returns 0.  */
    +
    +int
    +dyn_string_copy_cstr (dyn_string_t dest, const char *src)
    +{
    +  int length = strlen (src);
    +  /* Make room in DEST.  */
    +  if (dyn_string_resize (dest, length) == NULL)
    +    return 0;
    +  /* Copy DEST into SRC.  */
    +  strcpy (dest->s, src);
    +  /* Update the size of DEST.  */
    +  dest->length = length;
    +  return 1;
    +}
    +
    +/* Inserts SRC at the beginning of DEST.  DEST is expanded as
    +   necessary.  SRC and DEST must be distinct.  Returns 1 on success.
    +   On failure, if RETURN_ON_ALLOCATION_FAILURE, deletes DEST and
    +   returns 0.  */
    +
    +int
    +dyn_string_prepend (dyn_string_t dest, dyn_string_t src)
    +{
    +  return dyn_string_insert (dest, 0, src);
    +}
    +
    +/* Inserts SRC, a NUL-terminated string, at the beginning of DEST.
    +   DEST is expanded as necessary.  Returns 1 on success.  On failure,
    +   if RETURN_ON_ALLOCATION_FAILURE, deletes DEST and returns 0. */
    +
    +int
    +dyn_string_prepend_cstr (dyn_string_t dest, const char *src)
    +{
    +  return dyn_string_insert_cstr (dest, 0, src);
    +}
    +
    +/* Inserts SRC into DEST starting at position POS.  DEST is expanded
    +   as necessary.  SRC and DEST must be distinct.  Returns 1 on
    +   success.  On failure, if RETURN_ON_ALLOCATION_FAILURE, deletes DEST
    +   and returns 0.  */
    +
    +int
    +dyn_string_insert (dyn_string_t dest, int pos, dyn_string_t src)
    +{
    +  int i;
    +
    +  if (src == dest)
    +    abort ();
    +
    +  if (dyn_string_resize (dest, dest->length + src->length) == NULL)
    +    return 0;
    +  /* Make room for the insertion.  Be sure to copy the NUL.  */
    +  for (i = dest->length; i >= pos; --i)
    +    dest->s[i + src->length] = dest->s[i];
    +  /* Splice in the new stuff.  */
    +  strncpy (dest->s + pos, src->s, src->length);
    +  /* Compute the new length.  */
    +  dest->length += src->length;
    +  return 1;
    +}
    +
    +/* Inserts SRC, a NUL-terminated string, into DEST starting at
    +   position POS.  DEST is expanded as necessary.  Returns 1 on
    +   success.  On failure, RETURN_ON_ALLOCATION_FAILURE, deletes DEST
    +   and returns 0.  */
    +
    +int
    +dyn_string_insert_cstr (dyn_string_t dest, int pos, const char *src)
    +{
    +  int i;
    +  int length = strlen (src);
    +
    +  if (dyn_string_resize (dest, dest->length + length) == NULL)
    +    return 0;
    +  /* Make room for the insertion.  Be sure to copy the NUL.  */
    +  for (i = dest->length; i >= pos; --i)
    +    dest->s[i + length] = dest->s[i];
    +  /* Splice in the new stuff.  */
    +  strncpy (dest->s + pos, src, length);
    +  /* Compute the new length.  */
    +  dest->length += length;
    +  return 1;
    +}
    +
    +/* Inserts character C into DEST starting at position POS.  DEST is
    +   expanded as necessary.  Returns 1 on success.  On failure,
    +   RETURN_ON_ALLOCATION_FAILURE, deletes DEST and returns 0.  */
    +
    +int
    +dyn_string_insert_char (dyn_string_t dest, int pos, int c)
    +{
    +  int i;
    +
    +  if (dyn_string_resize (dest, dest->length + 1) == NULL)
    +    return 0;
    +  /* Make room for the insertion.  Be sure to copy the NUL.  */
    +  for (i = dest->length; i >= pos; --i)
    +    dest->s[i + 1] = dest->s[i];
    +  /* Add the new character.  */
    +  dest->s[pos] = c;
    +  /* Compute the new length.  */
    +  ++dest->length;
    +  return 1;
    +}
    +     
    +/* Append S to DS, resizing DS if necessary.  Returns 1 on success.
    +   On failure, if RETURN_ON_ALLOCATION_FAILURE, deletes DEST and
    +   returns 0.  */
    +
    +int
    +dyn_string_append (dyn_string_t dest, dyn_string_t s)
    +{
    +  if (dyn_string_resize (dest, dest->length + s->length) == 0)
    +    return 0;
    +  strcpy (dest->s + dest->length, s->s);
    +  dest->length += s->length;
    +  return 1;
    +}
    +
    +/* Append the NUL-terminated string S to DS, resizing DS if necessary.
    +   Returns 1 on success.  On failure, if RETURN_ON_ALLOCATION_FAILURE,
    +   deletes DEST and returns 0.  */
    +
    +int
    +dyn_string_append_cstr (dyn_string_t dest, const char *s)
    +{
    +  int len = strlen (s);
    +
    +  /* The new length is the old length plus the size of our string, plus
    +     one for the null at the end.  */
    +  if (dyn_string_resize (dest, dest->length + len) == NULL)
    +    return 0;
    +  strcpy (dest->s + dest->length, s);
    +  dest->length += len;
    +  return 1;
    +}
    +
    +/* Appends C to the end of DEST.  Returns 1 on success.  On failure,
    +   if RETURN_ON_ALLOCATION_FAILURE, deletes DEST and returns 0.  */
    +
    +int
    +dyn_string_append_char (dyn_string_t dest, int c)
    +{
    +  /* Make room for the extra character.  */
    +  if (dyn_string_resize (dest, dest->length + 1) == NULL)
    +    return 0;
    +  /* Append the character; it will overwrite the old NUL.  */
    +  dest->s[dest->length] = c;
    +  /* Add a new NUL at the end.  */
    +  dest->s[dest->length + 1] = '\0';
    +  /* Update the length.  */
    +  ++(dest->length);
    +  return 1;
    +}
    +
    +/* Sets the contents of DEST to the substring of SRC starting at START
    +   and ending before END.  START must be less than or equal to END,
    +   and both must be between zero and the length of SRC, inclusive.
    +   Returns 1 on success.  On failure, if RETURN_ON_ALLOCATION_FAILURE,
    +   deletes DEST and returns 0.  */
    +
    +int
    +dyn_string_substring (dyn_string_t dest, dyn_string_t src,
    +                      int start, int end)
    +{
    +  int i;
    +  int length = end - start;
    +
    +  if (start > end || start > src->length || end > src->length)
    +    abort ();
    +
    +  /* Make room for the substring.  */
    +  if (dyn_string_resize (dest, length) == NULL)
    +    return 0;
    +  /* Copy the characters in the substring,  */
    +  for (i = length; --i >= 0; )
    +    dest->s[i] = src->s[start + i];
    +  /* NUL-terimate the result.  */
    +  dest->s[length] = '\0';
    +  /* Record the length of the substring.  */
    +  dest->length = length;
    +
    +  return 1;
    +}
    +
    +/* Returns non-zero if DS1 and DS2 have the same contents.  */
    +
    +int
    +dyn_string_eq (dyn_string_t ds1, dyn_string_t ds2)
    +{
    +  /* If DS1 and DS2 have different lengths, they must not be the same.  */
    +  if (ds1->length != ds2->length)
    +    return 0;
    +  else
    +    return !strcmp (ds1->s, ds2->s);
    +}
    
  • GPL/DemanglerGnu/src/demangler_gnu/c/getopt1.c+184 0 added
    @@ -0,0 +1,184 @@
    +/* ###
    + * IP: GPL 3
    + * REVIEWED: YES
    + */
    +/* getopt_long and getopt_long_only entry points for GNU getopt.
    +   Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98,2005
    +     Free Software Foundation, Inc.
    +
    +   NOTE: This source is derived from an old version taken from the GNU C
    +   Library (glibc).
    +
    +   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, 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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301,
    +   USA.  */
    +
    +#ifdef HAVE_CONFIG_H
    +#include <config.h>
    +#endif
    +
    +#if !defined __STDC__ || !__STDC__
    +/* This is a separate conditional since some stdc systems
    +   reject `defined (const)'.  */
    +#ifndef const
    +#define const
    +#endif
    +#endif
    +
    +#include <stdio.h>
    +
    +#include "getopt.h"
    +
    +/* Comment out all this code if we are using the GNU C Library, and are not
    +   actually compiling the library itself.  This code is part of the GNU C
    +   Library, but also included in many other GNU distributions.  Compiling
    +   and linking in this code is a waste when using the GNU C library
    +   (especially if it is a shared library).  Rather than having every GNU
    +   program understand `configure --with-gnu-libc' and omit the object files,
    +   it is simpler to just do this in the source for each such file.  */
    +
    +#define GETOPT_INTERFACE_VERSION 2
    +#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
    +#include <gnu-versions.h>
    +#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
    +#define ELIDE_CODE
    +#endif
    +#endif
    +
    +#ifndef ELIDE_CODE
    +
    +
    +/* This needs to come after some library #include
    +   to get __GNU_LIBRARY__ defined.  */
    +#ifdef __GNU_LIBRARY__
    +#include <stdlib.h>
    +#endif
    +
    +#ifndef	NULL
    +#define NULL 0
    +#endif
    +
    +int
    +getopt_long (int argc,  char *const *argv,  const char *options,
    +             const struct option *long_options, int *opt_index)
    +{
    +  return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
    +}
    +
    +/* Like getopt_long, but '-' as well as '--' can indicate a long option.
    +   If an option that starts with '-' (not '--') doesn't match a long option,
    +   but does match a short option, it is parsed as a short option
    +   instead.  */
    +
    +int
    +getopt_long_only (int argc, char *const *argv, const char *options,
    +                  const struct option *long_options, int *opt_index)
    +{
    +  return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
    +}
    +
    +
    +#endif	/* Not ELIDE_CODE.  */
    +
    +#ifdef TEST
    +
    +#include <stdio.h>
    +
    +int
    +main (int argc, char **argv)
    +{
    +  int c;
    +  int digit_optind = 0;
    +
    +  while (1)
    +    {
    +      int this_option_optind = optind ? optind : 1;
    +      int option_index = 0;
    +      static struct option long_options[] =
    +      {
    +	{"add", 1, 0, 0},
    +	{"append", 0, 0, 0},
    +	{"delete", 1, 0, 0},
    +	{"verbose", 0, 0, 0},
    +	{"create", 0, 0, 0},
    +	{"file", 1, 0, 0},
    +	{0, 0, 0, 0}
    +      };
    +
    +      c = getopt_long (argc, argv, "abc:d:0123456789",
    +		       long_options, &option_index);
    +      if (c == -1)
    +	break;
    +
    +      switch (c)
    +	{
    +	case 0:
    +	  printf ("option %s", long_options[option_index].name);
    +	  if (optarg)
    +	    printf (" with arg %s", optarg);
    +	  printf ("\n");
    +	  break;
    +
    +	case '0':
    +	case '1':
    +	case '2':
    +	case '3':
    +	case '4':
    +	case '5':
    +	case '6':
    +	case '7':
    +	case '8':
    +	case '9':
    +	  if (digit_optind != 0 && digit_optind != this_option_optind)
    +	    printf ("digits occur in two different argv-elements.\n");
    +	  digit_optind = this_option_optind;
    +	  printf ("option %c\n", c);
    +	  break;
    +
    +	case 'a':
    +	  printf ("option a\n");
    +	  break;
    +
    +	case 'b':
    +	  printf ("option b\n");
    +	  break;
    +
    +	case 'c':
    +	  printf ("option c with value `%s'\n", optarg);
    +	  break;
    +
    +	case 'd':
    +	  printf ("option d with value `%s'\n", optarg);
    +	  break;
    +
    +	case '?':
    +	  break;
    +
    +	default:
    +	  printf ("?? getopt returned character code 0%o ??\n", c);
    +	}
    +    }
    +
    +  if (optind < argc)
    +    {
    +      printf ("non-option ARGV-elements: ");
    +      while (optind < argc)
    +	printf ("%s ", argv[optind++]);
    +      printf ("\n");
    +    }
    +
    +  exit (0);
    +}
    +
    +#endif /* TEST */
    
  • GPL/DemanglerGnu/src/demangler_gnu/c/getopt.c+1056 0 added
    @@ -0,0 +1,1056 @@
    +/* ###
    + * IP: GPL 3
    + * REVIEWED: YES
    + */
    +/* Getopt for GNU.
    +   NOTE: getopt is now part of the C library, so if you don't know what
    +   "Keep this file name-space clean" means, talk to drepper@gnu.org
    +   before changing it!
    +
    +   Copyright (C) 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
    +   1996, 1997, 1998, 2005 Free Software Foundation, Inc.
    +
    +   NOTE: This source is derived from an old version taken from the GNU C
    +   Library (glibc).
    +
    +   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, 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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301,
    +   USA.  */
    +
    +/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
    +   Ditto for AIX 3.2 and <stdlib.h>.  */
    +#ifndef _NO_PROTO
    +# define _NO_PROTO
    +#endif
    +
    +#ifdef HAVE_CONFIG_H
    +# include <config.h>
    +#endif
    +
    +#if !defined __STDC__ || !__STDC__
    +/* This is a separate conditional since some stdc systems
    +   reject `defined (const)'.  */
    +# ifndef const
    +#  define const
    +# endif
    +#endif
    +
    +#include "ansidecl.h"
    +#include <stdio.h>
    +
    +/* Comment out all this code if we are using the GNU C Library, and are not
    +   actually compiling the library itself.  This code is part of the GNU C
    +   Library, but also included in many other GNU distributions.  Compiling
    +   and linking in this code is a waste when using the GNU C library
    +   (especially if it is a shared library).  Rather than having every GNU
    +   program understand `configure --with-gnu-libc' and omit the object files,
    +   it is simpler to just do this in the source for each such file.  */
    +
    +#define GETOPT_INTERFACE_VERSION 2
    +#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
    +# include <gnu-versions.h>
    +# if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
    +#  define ELIDE_CODE
    +# endif
    +#endif
    +
    +#ifndef ELIDE_CODE
    +
    +
    +/* This needs to come after some library #include
    +   to get __GNU_LIBRARY__ defined.  */
    +#ifdef	__GNU_LIBRARY__
    +/* Don't include stdlib.h for non-GNU C libraries because some of them
    +   contain conflicting prototypes for getopt.  */
    +# include <stdlib.h>
    +# include <unistd.h>
    +#endif	/* GNU C library.  */
    +
    +#ifdef VMS
    +# include <unixlib.h>
    +# if HAVE_STRING_H - 0
    +#  include <string.h>
    +# endif
    +#endif
    +
    +#ifndef _
    +/* This is for other GNU distributions with internationalized messages.
    +   When compiling libc, the _ macro is predefined.  */
    +# if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC
    +#  include <libintl.h>
    +#  define _(msgid)	gettext (msgid)
    +# else
    +#  define _(msgid)	(msgid)
    +# endif
    +#endif
    +
    +/* This version of `getopt' appears to the caller like standard Unix `getopt'
    +   but it behaves differently for the user, since it allows the user
    +   to intersperse the options with the other arguments.
    +
    +   As `getopt' works, it permutes the elements of ARGV so that,
    +   when it is done, all the options precede everything else.  Thus
    +   all application programs are extended to handle flexible argument order.
    +
    +   Setting the environment variable POSIXLY_CORRECT disables permutation.
    +   Then the behavior is completely standard.
    +
    +   GNU application programs can use a third alternative mode in which
    +   they can distinguish the relative order of options and other arguments.  */
    +
    +#include "getopt.h"
    +
    +/* For communication from `getopt' to the caller.
    +   When `getopt' finds an option that takes an argument,
    +   the argument value is returned here.
    +   Also, when `ordering' is RETURN_IN_ORDER,
    +   each non-option ARGV-element is returned here.  */
    +
    +char *optarg = NULL;
    +
    +/* Index in ARGV of the next element to be scanned.
    +   This is used for communication to and from the caller
    +   and for communication between successive calls to `getopt'.
    +
    +   On entry to `getopt', zero means this is the first call; initialize.
    +
    +   When `getopt' returns -1, this is the index of the first of the
    +   non-option elements that the caller should itself scan.
    +
    +   Otherwise, `optind' communicates from one call to the next
    +   how much of ARGV has been scanned so far.  */
    +
    +/* 1003.2 says this must be 1 before any call.  */
    +int optind = 1;
    +
    +/* Formerly, initialization of getopt depended on optind==0, which
    +   causes problems with re-calling getopt as programs generally don't
    +   know that. */
    +
    +int __getopt_initialized = 0;
    +
    +/* The next char to be scanned in the option-element
    +   in which the last option character we returned was found.
    +   This allows us to pick up the scan where we left off.
    +
    +   If this is zero, or a null string, it means resume the scan
    +   by advancing to the next ARGV-element.  */
    +
    +static char *nextchar;
    +
    +/* Callers store zero here to inhibit the error message
    +   for unrecognized options.  */
    +
    +int opterr = 1;
    +
    +/* Set to an option character which was unrecognized.
    +   This must be initialized on some systems to avoid linking in the
    +   system's own getopt implementation.  */
    +
    +int optopt = '?';
    +
    +/* Describe how to deal with options that follow non-option ARGV-elements.
    +
    +   If the caller did not specify anything,
    +   the default is REQUIRE_ORDER if the environment variable
    +   POSIXLY_CORRECT is defined, PERMUTE otherwise.
    +
    +   REQUIRE_ORDER means don't recognize them as options;
    +   stop option processing when the first non-option is seen.
    +   This is what Unix does.
    +   This mode of operation is selected by either setting the environment
    +   variable POSIXLY_CORRECT, or using `+' as the first character
    +   of the list of option characters.
    +
    +   PERMUTE is the default.  We permute the contents of ARGV as we scan,
    +   so that eventually all the non-options are at the end.  This allows options
    +   to be given in any order, even with programs that were not written to
    +   expect this.
    +
    +   RETURN_IN_ORDER is an option available to programs that were written
    +   to expect options and other ARGV-elements in any order and that care about
    +   the ordering of the two.  We describe each non-option ARGV-element
    +   as if it were the argument of an option with character code 1.
    +   Using `-' as the first character of the list of option characters
    +   selects this mode of operation.
    +
    +   The special argument `--' forces an end of option-scanning regardless
    +   of the value of `ordering'.  In the case of RETURN_IN_ORDER, only
    +   `--' can cause `getopt' to return -1 with `optind' != ARGC.  */
    +
    +static enum
    +{
    +  REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
    +} ordering;
    +
    +/* Value of POSIXLY_CORRECT environment variable.  */
    +static char *posixly_correct;
    +
    +#ifdef	__GNU_LIBRARY__
    +/* We want to avoid inclusion of string.h with non-GNU libraries
    +   because there are many ways it can cause trouble.
    +   On some systems, it contains special magic macros that don't work
    +   in GCC.  */
    +# include <string.h>
    +# define my_index	strchr
    +#else
    +
    +# if HAVE_STRING_H
    +#  include <string.h>
    +# else
    +#  if HAVE_STRINGS_H
    +#   include <strings.h>
    +#  endif
    +# endif
    +
    +/* Avoid depending on library functions or files
    +   whose names are inconsistent.  */
    +
    +#if HAVE_STDLIB_H && HAVE_DECL_GETENV
    +#  include <stdlib.h>
    +#elif !defined(getenv)
    +#  ifdef __cplusplus
    +extern "C" {
    +#  endif /* __cplusplus */
    +extern char *getenv (const char *);
    +#  ifdef __cplusplus
    +}
    +#  endif /* __cplusplus */
    +#endif
    +
    +static char *
    +my_index (const char *str, int chr)
    +{
    +  while (*str)
    +    {
    +      if (*str == chr)
    +	return (char *) str;
    +      str++;
    +    }
    +  return 0;
    +}
    +
    +/* If using GCC, we can safely declare strlen this way.
    +   If not using GCC, it is ok not to declare it.  */
    +#ifdef __GNUC__
    +/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
    +   That was relevant to code that was here before.  */
    +# if (!defined __STDC__ || !__STDC__) && !defined strlen
    +/* gcc with -traditional declares the built-in strlen to return int,
    +   and has done so at least since version 2.4.5. -- rms.  */
    +extern int strlen (const char *);
    +# endif /* not __STDC__ */
    +#endif /* __GNUC__ */
    +
    +#endif /* not __GNU_LIBRARY__ */
    +
    +/* Handle permutation of arguments.  */
    +
    +/* Describe the part of ARGV that contains non-options that have
    +   been skipped.  `first_nonopt' is the index in ARGV of the first of them;
    +   `last_nonopt' is the index after the last of them.  */
    +
    +static int first_nonopt;
    +static int last_nonopt;
    +
    +#ifdef _LIBC
    +/* Bash 2.0 gives us an environment variable containing flags
    +   indicating ARGV elements that should not be considered arguments.  */
    +
    +/* Defined in getopt_init.c  */
    +extern char *__getopt_nonoption_flags;
    +
    +static int nonoption_flags_max_len;
    +static int nonoption_flags_len;
    +
    +static int original_argc;
    +static char *const *original_argv;
    +
    +/* Make sure the environment variable bash 2.0 puts in the environment
    +   is valid for the getopt call we must make sure that the ARGV passed
    +   to getopt is that one passed to the process.  */
    +static void
    +__attribute__ ((unused))
    +store_args_and_env (int argc, char *const *argv)
    +{
    +  /* XXX This is no good solution.  We should rather copy the args so
    +     that we can compare them later.  But we must not use malloc(3).  */
    +  original_argc = argc;
    +  original_argv = argv;
    +}
    +# ifdef text_set_element
    +text_set_element (__libc_subinit, store_args_and_env);
    +# endif /* text_set_element */
    +
    +# define SWAP_FLAGS(ch1, ch2) \
    +  if (nonoption_flags_len > 0)						      \
    +    {									      \
    +      char __tmp = __getopt_nonoption_flags[ch1];			      \
    +      __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2];	      \
    +      __getopt_nonoption_flags[ch2] = __tmp;				      \
    +    }
    +#else	/* !_LIBC */
    +# define SWAP_FLAGS(ch1, ch2)
    +#endif	/* _LIBC */
    +
    +/* Exchange two adjacent subsequences of ARGV.
    +   One subsequence is elements [first_nonopt,last_nonopt)
    +   which contains all the non-options that have been skipped so far.
    +   The other is elements [last_nonopt,optind), which contains all
    +   the options processed since those non-options were skipped.
    +
    +   `first_nonopt' and `last_nonopt' are relocated so that they describe
    +   the new indices of the non-options in ARGV after they are moved.  */
    +
    +#if defined __STDC__ && __STDC__
    +static void exchange (char **);
    +#endif
    +
    +static void
    +exchange (char **argv)
    +{
    +  int bottom = first_nonopt;
    +  int middle = last_nonopt;
    +  int top = optind;
    +  char *tem;
    +
    +  /* Exchange the shorter segment with the far end of the longer segment.
    +     That puts the shorter segment into the right place.
    +     It leaves the longer segment in the right place overall,
    +     but it consists of two parts that need to be swapped next.  */
    +
    +#ifdef _LIBC
    +  /* First make sure the handling of the `__getopt_nonoption_flags'
    +     string can work normally.  Our top argument must be in the range
    +     of the string.  */
    +  if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len)
    +    {
    +      /* We must extend the array.  The user plays games with us and
    +	 presents new arguments.  */
    +      char *new_str = (char *) malloc (top + 1);
    +      if (new_str == NULL)
    +	nonoption_flags_len = nonoption_flags_max_len = 0;
    +      else
    +	{
    +	  memset (mempcpy (new_str, __getopt_nonoption_flags,
    +			   nonoption_flags_max_len),
    +		  '\0', top + 1 - nonoption_flags_max_len);
    +	  nonoption_flags_max_len = top + 1;
    +	  __getopt_nonoption_flags = new_str;
    +	}
    +    }
    +#endif
    +
    +  while (top > middle && middle > bottom)
    +    {
    +      if (top - middle > middle - bottom)
    +	{
    +	  /* Bottom segment is the short one.  */
    +	  int len = middle - bottom;
    +	  register int i;
    +
    +	  /* Swap it with the top part of the top segment.  */
    +	  for (i = 0; i < len; i++)
    +	    {
    +	      tem = argv[bottom + i];
    +	      argv[bottom + i] = argv[top - (middle - bottom) + i];
    +	      argv[top - (middle - bottom) + i] = tem;
    +	      SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
    +	    }
    +	  /* Exclude the moved bottom segment from further swapping.  */
    +	  top -= len;
    +	}
    +      else
    +	{
    +	  /* Top segment is the short one.  */
    +	  int len = top - middle;
    +	  register int i;
    +
    +	  /* Swap it with the bottom part of the bottom segment.  */
    +	  for (i = 0; i < len; i++)
    +	    {
    +	      tem = argv[bottom + i];
    +	      argv[bottom + i] = argv[middle + i];
    +	      argv[middle + i] = tem;
    +	      SWAP_FLAGS (bottom + i, middle + i);
    +	    }
    +	  /* Exclude the moved top segment from further swapping.  */
    +	  bottom += len;
    +	}
    +    }
    +
    +  /* Update records for the slots the non-options now occupy.  */
    +
    +  first_nonopt += (optind - last_nonopt);
    +  last_nonopt = optind;
    +}
    +
    +/* Initialize the internal data when the first call is made.  */
    +
    +#if defined __STDC__ && __STDC__
    +static const char *_getopt_initialize (int, char *const *, const char *);
    +#endif
    +static const char *
    +_getopt_initialize (int argc ATTRIBUTE_UNUSED,
    +		    char *const *argv ATTRIBUTE_UNUSED,
    +		    const char *optstring)
    +{
    +  /* Start processing options with ARGV-element 1 (since ARGV-element 0
    +     is the program name); the sequence of previously skipped
    +     non-option ARGV-elements is empty.  */
    +
    +  first_nonopt = last_nonopt = optind;
    +
    +  nextchar = NULL;
    +
    +  posixly_correct = getenv ("POSIXLY_CORRECT");
    +
    +  /* Determine how to handle the ordering of options and nonoptions.  */
    +
    +  if (optstring[0] == '-')
    +    {
    +      ordering = RETURN_IN_ORDER;
    +      ++optstring;
    +    }
    +  else if (optstring[0] == '+')
    +    {
    +      ordering = REQUIRE_ORDER;
    +      ++optstring;
    +    }
    +  else if (posixly_correct != NULL)
    +    ordering = REQUIRE_ORDER;
    +  else
    +    ordering = PERMUTE;
    +
    +#ifdef _LIBC
    +  if (posixly_correct == NULL
    +      && argc == original_argc && argv == original_argv)
    +    {
    +      if (nonoption_flags_max_len == 0)
    +	{
    +	  if (__getopt_nonoption_flags == NULL
    +	      || __getopt_nonoption_flags[0] == '\0')
    +	    nonoption_flags_max_len = -1;
    +	  else
    +	    {
    +	      const char *orig_str = __getopt_nonoption_flags;
    +	      int len = nonoption_flags_max_len = strlen (orig_str);
    +	      if (nonoption_flags_max_len < argc)
    +		nonoption_flags_max_len = argc;
    +	      __getopt_nonoption_flags =
    +		(char *) malloc (nonoption_flags_max_len);
    +	      if (__getopt_nonoption_flags == NULL)
    +		nonoption_flags_max_len = -1;
    +	      else
    +		memset (mempcpy (__getopt_nonoption_flags, orig_str, len),
    +			'\0', nonoption_flags_max_len - len);
    +	    }
    +	}
    +      nonoption_flags_len = nonoption_flags_max_len;
    +    }
    +  else
    +    nonoption_flags_len = 0;
    +#endif
    +
    +  return optstring;
    +}
    +
    +/* Scan elements of ARGV (whose length is ARGC) for option characters
    +   given in OPTSTRING.
    +
    +   If an element of ARGV starts with '-', and is not exactly "-" or "--",
    +   then it is an option element.  The characters of this element
    +   (aside from the initial '-') are option characters.  If `getopt'
    +   is called repeatedly, it returns successively each of the option characters
    +   from each of the option elements.
    +
    +   If `getopt' finds another option character, it returns that character,
    +   updating `optind' and `nextchar' so that the next call to `getopt' can
    +   resume the scan with the following option character or ARGV-element.
    +
    +   If there are no more option characters, `getopt' returns -1.
    +   Then `optind' is the index in ARGV of the first ARGV-element
    +   that is not an option.  (The ARGV-elements have been permuted
    +   so that those that are not options now come last.)
    +
    +   OPTSTRING is a string containing the legitimate option characters.
    +   If an option character is seen that is not listed in OPTSTRING,
    +   return '?' after printing an error message.  If you set `opterr' to
    +   zero, the error message is suppressed but we still return '?'.
    +
    +   If a char in OPTSTRING is followed by a colon, that means it wants an arg,
    +   so the following text in the same ARGV-element, or the text of the following
    +   ARGV-element, is returned in `optarg'.  Two colons mean an option that
    +   wants an optional arg; if there is text in the current ARGV-element,
    +   it is returned in `optarg', otherwise `optarg' is set to zero.
    +
    +   If OPTSTRING starts with `-' or `+', it requests different methods of
    +   handling the non-option ARGV-elements.
    +   See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
    +
    +   Long-named options begin with `--' instead of `-'.
    +   Their names may be abbreviated as long as the abbreviation is unique
    +   or is an exact match for some defined option.  If they have an
    +   argument, it follows the option name in the same ARGV-element, separated
    +   from the option name by a `=', or else the in next ARGV-element.
    +   When `getopt' finds a long-named option, it returns 0 if that option's
    +   `flag' field is nonzero, the value of the option's `val' field
    +   if the `flag' field is zero.
    +
    +   The elements of ARGV aren't really const, because we permute them.
    +   But we pretend they're const in the prototype to be compatible
    +   with other systems.
    +
    +   LONGOPTS is a vector of `struct option' terminated by an
    +   element containing a name which is zero.
    +
    +   LONGIND returns the index in LONGOPT of the long-named option found.
    +   It is only valid when a long-named option has been found by the most
    +   recent call.
    +
    +   If LONG_ONLY is nonzero, '-' as well as '--' can introduce
    +   long-named options.  */
    +
    +int
    +_getopt_internal (int argc, char *const *argv, const char *optstring,
    +                  const struct option *longopts,
    +                  int *longind, int long_only)
    +{
    +  optarg = NULL;
    +
    +  if (optind == 0 || !__getopt_initialized)
    +    {
    +      if (optind == 0)
    +	optind = 1;	/* Don't scan ARGV[0], the program name.  */
    +      optstring = _getopt_initialize (argc, argv, optstring);
    +      __getopt_initialized = 1;
    +    }
    +
    +  /* Test whether ARGV[optind] points to a non-option argument.
    +     Either it does not have option syntax, or there is an environment flag
    +     from the shell indicating it is not an option.  The later information
    +     is only used when the used in the GNU libc.  */
    +#ifdef _LIBC
    +# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0'	      \
    +		      || (optind < nonoption_flags_len			      \
    +			  && __getopt_nonoption_flags[optind] == '1'))
    +#else
    +# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
    +#endif
    +
    +  if (nextchar == NULL || *nextchar == '\0')
    +    {
    +      /* Advance to the next ARGV-element.  */
    +
    +      /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
    +	 moved back by the user (who may also have changed the arguments).  */
    +      if (last_nonopt > optind)
    +	last_nonopt = optind;
    +      if (first_nonopt > optind)
    +	first_nonopt = optind;
    +
    +      if (ordering == PERMUTE)
    +	{
    +	  /* If we have just processed some options following some non-options,
    +	     exchange them so that the options come first.  */
    +
    +	  if (first_nonopt != last_nonopt && last_nonopt != optind)
    +	    exchange ((char **) argv);
    +	  else if (last_nonopt != optind)
    +	    first_nonopt = optind;
    +
    +	  /* Skip any additional non-options
    +	     and extend the range of non-options previously skipped.  */
    +
    +	  while (optind < argc && NONOPTION_P)
    +	    optind++;
    +	  last_nonopt = optind;
    +	}
    +
    +      /* The special ARGV-element `--' means premature end of options.
    +	 Skip it like a null option,
    +	 then exchange with previous non-options as if it were an option,
    +	 then skip everything else like a non-option.  */
    +
    +      if (optind != argc && !strcmp (argv[optind], "--"))
    +	{
    +	  optind++;
    +
    +	  if (first_nonopt != last_nonopt && last_nonopt != optind)
    +	    exchange ((char **) argv);
    +	  else if (first_nonopt == last_nonopt)
    +	    first_nonopt = optind;
    +	  last_nonopt = argc;
    +
    +	  optind = argc;
    +	}
    +
    +      /* If we have done all the ARGV-elements, stop the scan
    +	 and back over any non-options that we skipped and permuted.  */
    +
    +      if (optind == argc)
    +	{
    +	  /* Set the next-arg-index to point at the non-options
    +	     that we previously skipped, so the caller will digest them.  */
    +	  if (first_nonopt != last_nonopt)
    +	    optind = first_nonopt;
    +	  return -1;
    +	}
    +
    +      /* If we have come to a non-option and did not permute it,
    +	 either stop the scan or describe it to the caller and pass it by.  */
    +
    +      if (NONOPTION_P)
    +	{
    +	  if (ordering == REQUIRE_ORDER)
    +	    return -1;
    +	  optarg = argv[optind++];
    +	  return 1;
    +	}
    +
    +      /* We have found another option-ARGV-element.
    +	 Skip the initial punctuation.  */
    +
    +      nextchar = (argv[optind] + 1
    +		  + (longopts != NULL && argv[optind][1] == '-'));
    +    }
    +
    +  /* Decode the current option-ARGV-element.  */
    +
    +  /* Check whether the ARGV-element is a long option.
    +
    +     If long_only and the ARGV-element has the form "-f", where f is
    +     a valid short option, don't consider it an abbreviated form of
    +     a long option that starts with f.  Otherwise there would be no
    +     way to give the -f short option.
    +
    +     On the other hand, if there's a long option "fubar" and
    +     the ARGV-element is "-fu", do consider that an abbreviation of
    +     the long option, just like "--fu", and not "-f" with arg "u".
    +
    +     This distinction seems to be the most useful approach.  */
    +
    +  if (longopts != NULL
    +      && (argv[optind][1] == '-'
    +	  || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
    +    {
    +      char *nameend;
    +      const struct option *p;
    +      const struct option *pfound = NULL;
    +      int exact = 0;
    +      int ambig = 0;
    +      int indfound = -1;
    +      int option_index;
    +
    +      for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
    +	/* Do nothing.  */ ;
    +
    +      /* Test all long options for either exact match
    +	 or abbreviated matches.  */
    +      for (p = longopts, option_index = 0; p->name; p++, option_index++)
    +	if (!strncmp (p->name, nextchar, nameend - nextchar))
    +	  {
    +	    if ((unsigned int) (nameend - nextchar)
    +		== (unsigned int) strlen (p->name))
    +	      {
    +		/* Exact match found.  */
    +		pfound = p;
    +		indfound = option_index;
    +		exact = 1;
    +		break;
    +	      }
    +	    else if (pfound == NULL)
    +	      {
    +		/* First nonexact match found.  */
    +		pfound = p;
    +		indfound = option_index;
    +	      }
    +	    else
    +	      /* Second or later nonexact match found.  */
    +	      ambig = 1;
    +	  }
    +
    +      if (ambig && !exact)
    +	{
    +	  if (opterr)
    +	    fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
    +		     argv[0], argv[optind]);
    +	  nextchar += strlen (nextchar);
    +	  optind++;
    +	  optopt = 0;
    +	  return '?';
    +	}
    +
    +      if (pfound != NULL)
    +	{
    +	  option_index = indfound;
    +	  optind++;
    +	  if (*nameend)
    +	    {
    +	      /* Don't test has_arg with >, because some C compilers don't
    +		 allow it to be used on enums.  */
    +	      if (pfound->has_arg)
    +		optarg = nameend + 1;
    +	      else
    +		{
    +		  if (opterr)
    +		    {
    +		      if (argv[optind - 1][1] == '-')
    +			/* --option */
    +			fprintf (stderr,
    +				 _("%s: option `--%s' doesn't allow an argument\n"),
    +				 argv[0], pfound->name);
    +		      else
    +			/* +option or -option */
    +			fprintf (stderr,
    +				 _("%s: option `%c%s' doesn't allow an argument\n"),
    +				 argv[0], argv[optind - 1][0], pfound->name);
    +
    +		      nextchar += strlen (nextchar);
    +
    +		      optopt = pfound->val;
    +		      return '?';
    +		    }
    +		}
    +	    }
    +	  else if (pfound->has_arg == 1)
    +	    {
    +	      if (optind < argc)
    +		optarg = argv[optind++];
    +	      else
    +		{
    +		  if (opterr)
    +		    fprintf (stderr,
    +			   _("%s: option `%s' requires an argument\n"),
    +			   argv[0], argv[optind - 1]);
    +		  nextchar += strlen (nextchar);
    +		  optopt = pfound->val;
    +		  return optstring[0] == ':' ? ':' : '?';
    +		}
    +	    }
    +	  nextchar += strlen (nextchar);
    +	  if (longind != NULL)
    +	    *longind = option_index;
    +	  if (pfound->flag)
    +	    {
    +	      *(pfound->flag) = pfound->val;
    +	      return 0;
    +	    }
    +	  return pfound->val;
    +	}
    +
    +      /* Can't find it as a long option.  If this is not getopt_long_only,
    +	 or the option starts with '--' or is not a valid short
    +	 option, then it's an error.
    +	 Otherwise interpret it as a short option.  */
    +      if (!long_only || argv[optind][1] == '-'
    +	  || my_index (optstring, *nextchar) == NULL)
    +	{
    +	  if (opterr)
    +	    {
    +	      if (argv[optind][1] == '-')
    +		/* --option */
    +		fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
    +			 argv[0], nextchar);
    +	      else
    +		/* +option or -option */
    +		fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
    +			 argv[0], argv[optind][0], nextchar);
    +	    }
    +	  nextchar = (char *) "";
    +	  optind++;
    +	  optopt = 0;
    +	  return '?';
    +	}
    +    }
    +
    +  /* Look at and handle the next short option-character.  */
    +
    +  {
    +    char c = *nextchar++;
    +    char *temp = my_index (optstring, c);
    +
    +    /* Increment `optind' when we start to process its last character.  */
    +    if (*nextchar == '\0')
    +      ++optind;
    +
    +    if (temp == NULL || c == ':')
    +      {
    +	if (opterr)
    +	  {
    +	    if (posixly_correct)
    +	      /* 1003.2 specifies the format of this message.  */
    +	      fprintf (stderr, _("%s: illegal option -- %c\n"),
    +		       argv[0], c);
    +	    else
    +	      fprintf (stderr, _("%s: invalid option -- %c\n"),
    +		       argv[0], c);
    +	  }
    +	optopt = c;
    +	return '?';
    +      }
    +    /* Convenience. Treat POSIX -W foo same as long option --foo */
    +    if (temp[0] == 'W' && temp[1] == ';')
    +      {
    +	char *nameend;
    +	const struct option *p;
    +	const struct option *pfound = NULL;
    +	int exact = 0;
    +	int ambig = 0;
    +	int indfound = 0;
    +	int option_index;
    +
    +	/* This is an option that requires an argument.  */
    +	if (*nextchar != '\0')
    +	  {
    +	    optarg = nextchar;
    +	    /* If we end this ARGV-element by taking the rest as an arg,
    +	       we must advance to the next element now.  */
    +	    optind++;
    +	  }
    +	else if (optind == argc)
    +	  {
    +	    if (opterr)
    +	      {
    +		/* 1003.2 specifies the format of this message.  */
    +		fprintf (stderr, _("%s: option requires an argument -- %c\n"),
    +			 argv[0], c);
    +	      }
    +	    optopt = c;
    +	    if (optstring[0] == ':')
    +	      c = ':';
    +	    else
    +	      c = '?';
    +	    return c;
    +	  }
    +	else
    +	  /* We already incremented `optind' once;
    +	     increment it again when taking next ARGV-elt as argument.  */
    +	  optarg = argv[optind++];
    +
    +	/* optarg is now the argument, see if it's in the
    +	   table of longopts.  */
    +
    +	for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++)
    +	  /* Do nothing.  */ ;
    +
    +	/* Test all long options for either exact match
    +	   or abbreviated matches.  */
    +	for (p = longopts, option_index = 0; p->name; p++, option_index++)
    +	  if (!strncmp (p->name, nextchar, nameend - nextchar))
    +	    {
    +	      if ((unsigned int) (nameend - nextchar) == strlen (p->name))
    +		{
    +		  /* Exact match found.  */
    +		  pfound = p;
    +		  indfound = option_index;
    +		  exact = 1;
    +		  break;
    +		}
    +	      else if (pfound == NULL)
    +		{
    +		  /* First nonexact match found.  */
    +		  pfound = p;
    +		  indfound = option_index;
    +		}
    +	      else
    +		/* Second or later nonexact match found.  */
    +		ambig = 1;
    +	    }
    +	if (ambig && !exact)
    +	  {
    +	    if (opterr)
    +	      fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
    +		       argv[0], argv[optind]);
    +	    nextchar += strlen (nextchar);
    +	    optind++;
    +	    return '?';
    +	  }
    +	if (pfound != NULL)
    +	  {
    +	    option_index = indfound;
    +	    if (*nameend)
    +	      {
    +		/* Don't test has_arg with >, because some C compilers don't
    +		   allow it to be used on enums.  */
    +		if (pfound->has_arg)
    +		  optarg = nameend + 1;
    +		else
    +		  {
    +		    if (opterr)
    +		      fprintf (stderr, _("\
    +%s: option `-W %s' doesn't allow an argument\n"),
    +			       argv[0], pfound->name);
    +
    +		    nextchar += strlen (nextchar);
    +		    return '?';
    +		  }
    +	      }
    +	    else if (pfound->has_arg == 1)
    +	      {
    +		if (optind < argc)
    +		  optarg = argv[optind++];
    +		else
    +		  {
    +		    if (opterr)
    +		      fprintf (stderr,
    +			       _("%s: option `%s' requires an argument\n"),
    +			       argv[0], argv[optind - 1]);
    +		    nextchar += strlen (nextchar);
    +		    return optstring[0] == ':' ? ':' : '?';
    +		  }
    +	      }
    +	    nextchar += strlen (nextchar);
    +	    if (longind != NULL)
    +	      *longind = option_index;
    +	    if (pfound->flag)
    +	      {
    +		*(pfound->flag) = pfound->val;
    +		return 0;
    +	      }
    +	    return pfound->val;
    +	  }
    +	  nextchar = NULL;
    +	  return 'W';	/* Let the application handle it.   */
    +      }
    +    if (temp[1] == ':')
    +      {
    +	if (temp[2] == ':')
    +	  {
    +	    /* This is an option that accepts an argument optionally.  */
    +	    if (*nextchar != '\0')
    +	      {
    +		optarg = nextchar;
    +		optind++;
    +	      }
    +	    else
    +	      optarg = NULL;
    +	    nextchar = NULL;
    +	  }
    +	else
    +	  {
    +	    /* This is an option that requires an argument.  */
    +	    if (*nextchar != '\0')
    +	      {
    +		optarg = nextchar;
    +		/* If we end this ARGV-element by taking the rest as an arg,
    +		   we must advance to the next element now.  */
    +		optind++;
    +	      }
    +	    else if (optind == argc)
    +	      {
    +		if (opterr)
    +		  {
    +		    /* 1003.2 specifies the format of this message.  */
    +		    fprintf (stderr,
    +			   _("%s: option requires an argument -- %c\n"),
    +			   argv[0], c);
    +		  }
    +		optopt = c;
    +		if (optstring[0] == ':')
    +		  c = ':';
    +		else
    +		  c = '?';
    +	      }
    +	    else
    +	      /* We already incremented `optind' once;
    +		 increment it again when taking next ARGV-elt as argument.  */
    +	      optarg = argv[optind++];
    +	    nextchar = NULL;
    +	  }
    +      }
    +    return c;
    +  }
    +}
    +
    +int
    +getopt (int argc, char *const *argv, const char *optstring)
    +{
    +  return _getopt_internal (argc, argv, optstring,
    +			   (const struct option *) 0,
    +			   (int *) 0,
    +			   0);
    +}
    +
    +#endif	/* Not ELIDE_CODE.  */
    +
    +#ifdef TEST
    +
    +/* Compile with -DTEST to make an executable for use in testing
    +   the above definition of `getopt'.  */
    +
    +int
    +main (int argc, char **argv)
    +{
    +  int c;
    +  int digit_optind = 0;
    +
    +  while (1)
    +    {
    +      int this_option_optind = optind ? optind : 1;
    +
    +      c = getopt (argc, argv, "abc:d:0123456789");
    +      if (c == -1)
    +	break;
    +
    +      switch (c)
    +	{
    +	case '0':
    +	case '1':
    +	case '2':
    +	case '3':
    +	case '4':
    +	case '5':
    +	case '6':
    +	case '7':
    +	case '8':
    +	case '9':
    +	  if (digit_optind != 0 && digit_optind != this_option_optind)
    +	    printf ("digits occur in two different argv-elements.\n");
    +	  digit_optind = this_option_optind;
    +	  printf ("option %c\n", c);
    +	  break;
    +
    +	case 'a':
    +	  printf ("option a\n");
    +	  break;
    +
    +	case 'b':
    +	  printf ("option b\n");
    +	  break;
    +
    +	case 'c':
    +	  printf ("option c with value `%s'\n", optarg);
    +	  break;
    +
    +	case '?':
    +	  break;
    +
    +	default:
    +	  printf ("?? getopt returned character code 0%o ??\n", c);
    +	}
    +    }
    +
    +  if (optind < argc)
    +    {
    +      printf ("non-option ARGV-elements: ");
    +      while (optind < argc)
    +	printf ("%s ", argv[optind++]);
    +      printf ("\n");
    +    }
    +
    +  exit (0);
    +}
    +
    +#endif /* TEST */
    
  • GPL/DemanglerGnu/src/demangler_gnu/c/safe-ctype.c+259 0 added
    @@ -0,0 +1,259 @@
    +/* ###
    + * IP: LGPL 2.1
    + * REVIEWED: YES
    + */
    +/* <ctype.h> replacement macros.
    +
    +   Copyright (C) 2000, 2001, 2002, 2003, 2004,
    +   2005 Free Software Foundation, Inc.
    +   Contributed by Zack Weinberg <zackw@stanford.edu>.
    +
    +This file is part of the libiberty library.
    +Libiberty is free software; you can redistribute it and/or
    +modify it under the terms of the GNU Library General Public
    +License as published by the Free Software Foundation; either
    +version 2 of the License, or (at your option) any later version.
    +
    +Libiberty 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
    +Library General Public License for more details.
    +
    +You should have received a copy of the GNU Library General Public
    +License along with libiberty; see the file COPYING.LIB.  If
    +not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
    +Boston, MA 02110-1301, USA.  */
    +
    +/*
    +
    +@defvr Extension HOST_CHARSET
    +This macro indicates the basic character set and encoding used by the
    +host: more precisely, the encoding used for character constants in
    +preprocessor @samp{#if} statements (the C "execution character set").
    +It is defined by @file{safe-ctype.h}, and will be an integer constant
    +with one of the following values:
    +
    +@ftable @code
    +@item HOST_CHARSET_UNKNOWN
    +The host character set is unknown - that is, not one of the next two
    +possibilities.
    +
    +@item HOST_CHARSET_ASCII
    +The host character set is ASCII.
    +
    +@item HOST_CHARSET_EBCDIC
    +The host character set is some variant of EBCDIC.  (Only one of the
    +nineteen EBCDIC varying characters is tested; exercise caution.)
    +@end ftable
    +@end defvr
    +
    +@deffn  Extension ISALPHA  (@var{c})
    +@deffnx Extension ISALNUM  (@var{c})
    +@deffnx Extension ISBLANK  (@var{c})
    +@deffnx Extension ISCNTRL  (@var{c})
    +@deffnx Extension ISDIGIT  (@var{c})
    +@deffnx Extension ISGRAPH  (@var{c})
    +@deffnx Extension ISLOWER  (@var{c})
    +@deffnx Extension ISPRINT  (@var{c})
    +@deffnx Extension ISPUNCT  (@var{c})
    +@deffnx Extension ISSPACE  (@var{c})
    +@deffnx Extension ISUPPER  (@var{c})
    +@deffnx Extension ISXDIGIT (@var{c})
    +
    +These twelve macros are defined by @file{safe-ctype.h}.  Each has the
    +same meaning as the corresponding macro (with name in lowercase)
    +defined by the standard header @file{ctype.h}.  For example,
    +@code{ISALPHA} returns true for alphabetic characters and false for
    +others.  However, there are two differences between these macros and
    +those provided by @file{ctype.h}:
    +
    +@itemize @bullet
    +@item These macros are guaranteed to have well-defined behavior for all 
    +values representable by @code{signed char} and @code{unsigned char}, and
    +for @code{EOF}.
    +
    +@item These macros ignore the current locale; they are true for these
    +fixed sets of characters:
    +@multitable {@code{XDIGIT}} {yada yada yada yada yada yada yada yada}
    +@item @code{ALPHA}  @tab @kbd{A-Za-z}
    +@item @code{ALNUM}  @tab @kbd{A-Za-z0-9}
    +@item @code{BLANK}  @tab @kbd{space tab}
    +@item @code{CNTRL}  @tab @code{!PRINT}
    +@item @code{DIGIT}  @tab @kbd{0-9}
    +@item @code{GRAPH}  @tab @code{ALNUM || PUNCT}
    +@item @code{LOWER}  @tab @kbd{a-z}
    +@item @code{PRINT}  @tab @code{GRAPH ||} @kbd{space}
    +@item @code{PUNCT}  @tab @kbd{`~!@@#$%^&*()_-=+[@{]@}\|;:'",<.>/?}
    +@item @code{SPACE}  @tab @kbd{space tab \n \r \f \v}
    +@item @code{UPPER}  @tab @kbd{A-Z}
    +@item @code{XDIGIT} @tab @kbd{0-9A-Fa-f}
    +@end multitable
    +
    +Note that, if the host character set is ASCII or a superset thereof,
    +all these macros will return false for all values of @code{char} outside
    +the range of 7-bit ASCII.  In particular, both ISPRINT and ISCNTRL return
    +false for characters with numeric values from 128 to 255.
    +@end itemize
    +@end deffn
    +
    +@deffn  Extension ISIDNUM         (@var{c})
    +@deffnx Extension ISIDST          (@var{c})
    +@deffnx Extension IS_VSPACE       (@var{c})
    +@deffnx Extension IS_NVSPACE      (@var{c})
    +@deffnx Extension IS_SPACE_OR_NUL (@var{c})
    +@deffnx Extension IS_ISOBASIC     (@var{c})
    +These six macros are defined by @file{safe-ctype.h} and provide
    +additional character classes which are useful when doing lexical
    +analysis of C or similar languages.  They are true for the following
    +sets of characters:
    +
    +@multitable {@code{SPACE_OR_NUL}} {yada yada yada yada yada yada yada yada}
    +@item @code{IDNUM}        @tab @kbd{A-Za-z0-9_}
    +@item @code{IDST}         @tab @kbd{A-Za-z_}
    +@item @code{VSPACE}       @tab @kbd{\r \n}
    +@item @code{NVSPACE}      @tab @kbd{space tab \f \v \0}
    +@item @code{SPACE_OR_NUL} @tab @code{VSPACE || NVSPACE}
    +@item @code{ISOBASIC}     @tab @code{VSPACE || NVSPACE || PRINT}
    +@end multitable
    +@end deffn
    +
    +*/
    +
    +#include "ansidecl.h"
    +#include <safe-ctype.h>
    +#include <stdio.h>  /* for EOF */
    +
    +#if EOF != -1
    + #error "<safe-ctype.h> requires EOF == -1"
    +#endif
    +
    +/* Shorthand */
    +#define bl _sch_isblank
    +#define cn _sch_iscntrl
    +#define di _sch_isdigit
    +#define is _sch_isidst
    +#define lo _sch_islower
    +#define nv _sch_isnvsp
    +#define pn _sch_ispunct
    +#define pr _sch_isprint
    +#define sp _sch_isspace
    +#define up _sch_isupper
    +#define vs _sch_isvsp
    +#define xd _sch_isxdigit
    +
    +/* Masks.  */
    +#define L  (const unsigned short) (lo|is   |pr)	/* lower case letter */
    +#define XL (const unsigned short) (lo|is|xd|pr)	/* lowercase hex digit */
    +#define U  (const unsigned short) (up|is   |pr)	/* upper case letter */
    +#define XU (const unsigned short) (up|is|xd|pr)	/* uppercase hex digit */
    +#define D  (const unsigned short) (di   |xd|pr)	/* decimal digit */
    +#define P  (const unsigned short) (pn      |pr)	/* punctuation */
    +#define _  (const unsigned short) (pn|is   |pr)	/* underscore */
    +
    +#define C  (const unsigned short) (         cn)	/* control character */
    +#define Z  (const unsigned short) (nv      |cn)	/* NUL */
    +#define M  (const unsigned short) (nv|sp   |cn)	/* cursor movement: \f \v */
    +#define V  (const unsigned short) (vs|sp   |cn)	/* vertical space: \r \n */
    +#define T  (const unsigned short) (nv|sp|bl|cn)	/* tab */
    +#define S  (const unsigned short) (nv|sp|bl|pr)	/* space */
    +
    +/* Are we ASCII? */
    +#if HOST_CHARSET == HOST_CHARSET_ASCII
    +
    +const unsigned short _sch_istable[256] =
    +{
    +  Z,  C,  C,  C,   C,  C,  C,  C,   /* NUL SOH STX ETX  EOT ENQ ACK BEL */
    +  C,  T,  V,  M,   M,  V,  C,  C,   /* BS  HT  LF  VT   FF  CR  SO  SI  */
    +  C,  C,  C,  C,   C,  C,  C,  C,   /* DLE DC1 DC2 DC3  DC4 NAK SYN ETB */
    +  C,  C,  C,  C,   C,  C,  C,  C,   /* CAN EM  SUB ESC  FS  GS  RS  US  */
    +  S,  P,  P,  P,   P,  P,  P,  P,   /* SP  !   "   #    $   %   &   '   */
    +  P,  P,  P,  P,   P,  P,  P,  P,   /* (   )   *   +    ,   -   .   /   */
    +  D,  D,  D,  D,   D,  D,  D,  D,   /* 0   1   2   3    4   5   6   7   */
    +  D,  D,  P,  P,   P,  P,  P,  P,   /* 8   9   :   ;    <   =   >   ?   */
    +  P, XU, XU, XU,  XU, XU, XU,  U,   /* @   A   B   C    D   E   F   G   */
    +  U,  U,  U,  U,   U,  U,  U,  U,   /* H   I   J   K    L   M   N   O   */
    +  U,  U,  U,  U,   U,  U,  U,  U,   /* P   Q   R   S    T   U   V   W   */
    +  U,  U,  U,  P,   P,  P,  P,  _,   /* X   Y   Z   [    \   ]   ^   _   */
    +  P, XL, XL, XL,  XL, XL, XL,  L,   /* `   a   b   c    d   e   f   g   */
    +  L,  L,  L,  L,   L,  L,  L,  L,   /* h   i   j   k    l   m   n   o   */
    +  L,  L,  L,  L,   L,  L,  L,  L,   /* p   q   r   s    t   u   v   w   */
    +  L,  L,  L,  P,   P,  P,  P,  C,   /* x   y   z   {    |   }   ~   DEL */
    +
    +  /* high half of unsigned char is locale-specific, so all tests are
    +     false in "C" locale */
    +  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,
    +  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,
    +  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,
    +  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,
    +
    +  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,
    +  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,
    +  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,
    +  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,
    +};
    +
    +const unsigned char _sch_tolower[256] =
    +{
    +   0,  1,  2,  3,   4,  5,  6,  7,   8,  9, 10, 11,  12, 13, 14, 15,
    +  16, 17, 18, 19,  20, 21, 22, 23,  24, 25, 26, 27,  28, 29, 30, 31,
    +  32, 33, 34, 35,  36, 37, 38, 39,  40, 41, 42, 43,  44, 45, 46, 47,
    +  48, 49, 50, 51,  52, 53, 54, 55,  56, 57, 58, 59,  60, 61, 62, 63,
    +  64,
    +
    +  'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
    +  'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
    +
    +  91, 92, 93, 94, 95, 96,
    +
    +  'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
    +  'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
    +
    + 123,124,125,126,127,
    +
    + 128,129,130,131, 132,133,134,135, 136,137,138,139, 140,141,142,143,
    + 144,145,146,147, 148,149,150,151, 152,153,154,155, 156,157,158,159,
    + 160,161,162,163, 164,165,166,167, 168,169,170,171, 172,173,174,175,
    + 176,177,178,179, 180,181,182,183, 184,185,186,187, 188,189,190,191,
    +
    + 192,193,194,195, 196,197,198,199, 200,201,202,203, 204,205,206,207,
    + 208,209,210,211, 212,213,214,215, 216,217,218,219, 220,221,222,223,
    + 224,225,226,227, 228,229,230,231, 232,233,234,235, 236,237,238,239,
    + 240,241,242,243, 244,245,246,247, 248,249,250,251, 252,253,254,255,
    +};
    +
    +const unsigned char _sch_toupper[256] =
    +{
    +   0,  1,  2,  3,   4,  5,  6,  7,   8,  9, 10, 11,  12, 13, 14, 15,
    +  16, 17, 18, 19,  20, 21, 22, 23,  24, 25, 26, 27,  28, 29, 30, 31,
    +  32, 33, 34, 35,  36, 37, 38, 39,  40, 41, 42, 43,  44, 45, 46, 47,
    +  48, 49, 50, 51,  52, 53, 54, 55,  56, 57, 58, 59,  60, 61, 62, 63,
    +  64,
    +
    +  'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
    +  'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
    +
    +  91, 92, 93, 94, 95, 96,
    +
    +  'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
    +  'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
    +
    + 123,124,125,126,127,
    +
    + 128,129,130,131, 132,133,134,135, 136,137,138,139, 140,141,142,143,
    + 144,145,146,147, 148,149,150,151, 152,153,154,155, 156,157,158,159,
    + 160,161,162,163, 164,165,166,167, 168,169,170,171, 172,173,174,175,
    + 176,177,178,179, 180,181,182,183, 184,185,186,187, 188,189,190,191,
    +
    + 192,193,194,195, 196,197,198,199, 200,201,202,203, 204,205,206,207,
    + 208,209,210,211, 212,213,214,215, 216,217,218,219, 220,221,222,223,
    + 224,225,226,227, 228,229,230,231, 232,233,234,235, 236,237,238,239,
    + 240,241,242,243, 244,245,246,247, 248,249,250,251, 252,253,254,255,
    +};
    +
    +#else
    +# if HOST_CHARSET == HOST_CHARSET_EBCDIC
    +  #error "FIXME: write tables for EBCDIC"
    +# else
    +  #error "Unrecognized host character set"
    +# endif
    +#endif
    
  • GPL/DemanglerGnu/src/demangler_gnu/c/xexit.c+56 0 added
    @@ -0,0 +1,56 @@
    +/* ###
    + * IP: LGPL 2.1
    + * REVIEWED: YES
    + */
    +/* xexit.c -- Run any exit handlers, then exit.
    +   Copyright (C) 1994, 95, 1997 Free Software Foundation, Inc.
    +
    +This file is part of the libiberty library.
    +Libiberty is free software; you can redistribute it and/or
    +modify it under the terms of the GNU Library General Public
    +License as published by the Free Software Foundation; either
    +version 2 of the License, or (at your option) any later version.
    +
    +Libiberty 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
    +Library General Public License for more details.
    +
    +You should have received a copy of the GNU Library General Public
    +License along with libiberty; see the file COPYING.LIB.  If not, write
    +to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
    +Boston, MA 02110-1301, USA.  */
    +
    +/*
    +
    +@deftypefn Replacement void xexit (int @var{code})
    +
    +Terminates the program.  If any functions have been registered with
    +the @code{xatexit} replacement function, they will be called first.
    +Termination is handled via the system's normal @code{exit} call.
    +
    +@end deftypefn
    +
    +*/
    +
    +#ifdef HAVE_CONFIG_H
    +#include "config.h"
    +#endif
    +#include <stdio.h>
    +#ifdef HAVE_STDLIB_H
    +#include <stdlib.h>
    +#endif
    +#include "libiberty.h"
    +
    +
    +/* This variable is set by xatexit if it is called.  This way, xmalloc
    +   doesn't drag xatexit into the link.  */
    +void (*_xexit_cleanup) (void);
    +
    +void
    +xexit (int code)
    +{
    +  if (_xexit_cleanup != NULL)
    +    (*_xexit_cleanup) ();
    +  exit (code);
    +}
    
  • GPL/DemanglerGnu/src/demangler_gnu/c/xstrdup.c+41 0 added
    @@ -0,0 +1,41 @@
    +/* ###
    + * IP: LGPL 2.1
    + * REVIEWED: YES
    + * NOTE: license is not in file, but in the directory from whence it came: binutils-2.24/libiberty/COPYING.LIB
    + */
    +/* xstrdup.c -- Duplicate a string in memory, using xmalloc.
    +   This trivial function is in the public domain.
    +   Ian Lance Taylor, Cygnus Support, December 1995.  */
    +
    +/*
    +
    +@deftypefn Replacement char* xstrdup (const char *@var{s})
    +
    +Duplicates a character string without fail, using @code{xmalloc} to
    +obtain memory.
    +
    +@end deftypefn
    +
    +*/
    +
    +#ifdef HAVE_CONFIG_H
    +#include "config.h"
    +#endif
    +#include <sys/types.h>
    +#ifdef HAVE_STRING_H
    +#include <string.h>
    +#else
    +# ifdef HAVE_STRINGS_H
    +#  include <strings.h>
    +# endif
    +#endif
    +#include "ansidecl.h"
    +#include "libiberty.h"
    +
    +char *
    +xstrdup (const char *s)
    +{
    +  register size_t len = strlen (s) + 1;
    +  register char *ret = XNEWVEC (char, len);
    +  return (char *) memcpy (ret, s, len);
    +}
    
  • GPL/DemanglerGnu/src/demangler_gnu/headers/ansidecl.h+445 0 added
    @@ -0,0 +1,445 @@
    +/* ###
    + * IP: GPL 3
    + * REVIEWED: YES
    + */
    +/* ANSI and traditional C compatability macros
    +   Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
    +   2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010
    +   Free Software Foundation, Inc.
    +   This file is part of the GNU C Library.
    +
    +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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
    +
    +/* ANSI and traditional C compatibility macros
    +
    +   ANSI C is assumed if __STDC__ is #defined.
    +
    +   Macro		ANSI C definition	Traditional C definition
    +   -----		---- - ----------	----------- - ----------
    +   ANSI_PROTOTYPES	1			not defined
    +   PTR			`void *'		`char *'
    +   PTRCONST		`void *const'		`char *'
    +   LONG_DOUBLE		`long double'		`double'
    +   const		not defined		`'
    +   volatile		not defined		`'
    +   signed		not defined		`'
    +   VA_START(ap, var)	va_start(ap, var)	va_start(ap)
    +
    +   Note that it is safe to write "void foo();" indicating a function
    +   with no return value, in all K+R compilers we have been able to test.
    +
    +   For declaring functions with prototypes, we also provide these:
    +
    +   PARAMS ((prototype))
    +   -- for functions which take a fixed number of arguments.  Use this
    +   when declaring the function.  When defining the function, write a
    +   K+R style argument list.  For example:
    +
    +	char *strcpy PARAMS ((char *dest, char *source));
    +	...
    +	char *
    +	strcpy (dest, source)
    +	     char *dest;
    +	     char *source;
    +	{ ... }
    +
    +
    +   VPARAMS ((prototype, ...))
    +   -- for functions which take a variable number of arguments.  Use
    +   PARAMS to declare the function, VPARAMS to define it.  For example:
    +
    +	int printf PARAMS ((const char *format, ...));
    +	...
    +	int
    +	printf VPARAMS ((const char *format, ...))
    +	{
    +	   ...
    +	}
    +
    +   For writing functions which take variable numbers of arguments, we
    +   also provide the VA_OPEN, VA_CLOSE, and VA_FIXEDARG macros.  These
    +   hide the differences between K+R <varargs.h> and C89 <stdarg.h> more
    +   thoroughly than the simple VA_START() macro mentioned above.
    +
    +   VA_OPEN and VA_CLOSE are used *instead of* va_start and va_end.
    +   Immediately after VA_OPEN, put a sequence of VA_FIXEDARG calls
    +   corresponding to the list of fixed arguments.  Then use va_arg
    +   normally to get the variable arguments, or pass your va_list object
    +   around.  You do not declare the va_list yourself; VA_OPEN does it
    +   for you.
    +
    +   Here is a complete example:
    +
    +	int
    +	printf VPARAMS ((const char *format, ...))
    +	{
    +	   int result;
    +
    +	   VA_OPEN (ap, format);
    +	   VA_FIXEDARG (ap, const char *, format);
    +
    +	   result = vfprintf (stdout, format, ap);
    +	   VA_CLOSE (ap);
    +
    +	   return result;
    +	}
    +
    +
    +   You can declare variables either before or after the VA_OPEN,
    +   VA_FIXEDARG sequence.  Also, VA_OPEN and VA_CLOSE are the beginning
    +   and end of a block.  They must appear at the same nesting level,
    +   and any variables declared after VA_OPEN go out of scope at
    +   VA_CLOSE.  Unfortunately, with a K+R compiler, that includes the
    +   argument list.  You can have multiple instances of VA_OPEN/VA_CLOSE
    +   pairs in a single function in case you need to traverse the
    +   argument list more than once.
    +
    +   For ease of writing code which uses GCC extensions but needs to be
    +   portable to other compilers, we provide the GCC_VERSION macro that
    +   simplifies testing __GNUC__ and __GNUC_MINOR__ together, and various
    +   wrappers around __attribute__.  Also, __extension__ will be #defined
    +   to nothing if it doesn't work.  See below.
    +
    +   This header also defines a lot of obsolete macros:
    +   CONST, VOLATILE, SIGNED, PROTO, EXFUN, DEFUN, DEFUN_VOID,
    +   AND, DOTS, NOARGS.  Don't use them.  */
    +
    +#ifndef	_ANSIDECL_H
    +#define _ANSIDECL_H	1
    +
    +#ifdef __cplusplus
    +extern "C" {
    +#endif
    +
    +/* Every source file includes this file,
    +   so they will all get the switch for lint.  */
    +/* LINTLIBRARY */
    +
    +/* Using MACRO(x,y) in cpp #if conditionals does not work with some
    +   older preprocessors.  Thus we can't define something like this:
    +
    +#define HAVE_GCC_VERSION(MAJOR, MINOR) \
    +  (__GNUC__ > (MAJOR) || (__GNUC__ == (MAJOR) && __GNUC_MINOR__ >= (MINOR)))
    +
    +and then test "#if HAVE_GCC_VERSION(2,7)".
    +
    +So instead we use the macro below and test it against specific values.  */
    +
    +/* This macro simplifies testing whether we are using gcc, and if it
    +   is of a particular minimum version. (Both major & minor numbers are
    +   significant.)  This macro will evaluate to 0 if we are not using
    +   gcc at all.  */
    +#ifndef GCC_VERSION
    +#define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
    +#endif /* GCC_VERSION */
    +
    +#if defined (__STDC__) || defined(__cplusplus) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) || defined(_WIN32)
    +/* All known AIX compilers implement these things (but don't always
    +   define __STDC__).  The RISC/OS MIPS compiler defines these things
    +   in SVR4 mode, but does not define __STDC__.  */
    +/* eraxxon@alumni.rice.edu: The Compaq C++ compiler, unlike many other
    +   C++ compilers, does not define __STDC__, though it acts as if this
    +   was so. (Verified versions: 5.7, 6.2, 6.3, 6.5) */
    +
    +#define ANSI_PROTOTYPES	1
    +#define PTR		void *
    +#define PTRCONST	void *const
    +#define LONG_DOUBLE	long double
    +
    +/* PARAMS is often defined elsewhere (e.g. by libintl.h), so wrap it in
    +   a #ifndef.  */
    +#ifndef PARAMS
    +#define PARAMS(ARGS)		ARGS
    +#endif
    +
    +#define VPARAMS(ARGS)		ARGS
    +#define VA_START(VA_LIST, VAR)	va_start(VA_LIST, VAR)
    +
    +/* variadic function helper macros */
    +/* "struct Qdmy" swallows the semicolon after VA_OPEN/VA_FIXEDARG's
    +   use without inhibiting further decls and without declaring an
    +   actual variable.  */
    +#define VA_OPEN(AP, VAR)	{ va_list AP; va_start(AP, VAR); { struct Qdmy
    +#define VA_CLOSE(AP)		} va_end(AP); }
    +#define VA_FIXEDARG(AP, T, N)	struct Qdmy
    + 
    +#undef const
    +#undef volatile
    +#undef signed
    +
    +/* inline requires special treatment; it's in C99, and GCC >=2.7 supports
    +   it too, but it's not in C89.  */
    +#undef inline
    +#if __STDC_VERSION__ >= 199901L || defined(__cplusplus) || (defined(__SUNPRO_C) && defined(__C99FEATURES__))
    +/* it's a keyword */
    +#else
    +# if GCC_VERSION >= 2007
    +#  define inline __inline__   /* __inline__ prevents -pedantic warnings */
    +# else
    +#  define inline  /* nothing */
    +# endif
    +#endif
    +
    +/* These are obsolete.  Do not use.  */
    +#ifndef IN_GCC
    +#define CONST		const
    +#define VOLATILE	volatile
    +#define SIGNED		signed
    +
    +#define PROTO(type, name, arglist)	type name arglist
    +#define EXFUN(name, proto)		name proto
    +#define DEFUN(name, arglist, args)	name(args)
    +#define DEFUN_VOID(name)		name(void)
    +#define AND		,
    +#define DOTS		, ...
    +#define NOARGS		void
    +#endif /* ! IN_GCC */
    +
    +#else	/* Not ANSI C.  */
    +
    +#undef  ANSI_PROTOTYPES
    +#define PTR		char *
    +#define PTRCONST	PTR
    +#define LONG_DOUBLE	double
    +
    +#define PARAMS(args)		()
    +#define VPARAMS(args)		(va_alist) va_dcl
    +#define VA_START(va_list, var)	va_start(va_list)
    +
    +#define VA_OPEN(AP, VAR)		{ va_list AP; va_start(AP); { struct Qdmy
    +#define VA_CLOSE(AP)			} va_end(AP); }
    +#define VA_FIXEDARG(AP, TYPE, NAME)	TYPE NAME = va_arg(AP, TYPE)
    +
    +/* some systems define these in header files for non-ansi mode */
    +#undef const
    +#undef volatile
    +#undef signed
    +#undef inline
    +#define const
    +#define volatile
    +#define signed
    +#define inline
    +
    +#ifndef IN_GCC
    +#define CONST
    +#define VOLATILE
    +#define SIGNED
    +
    +#define PROTO(type, name, arglist)	type name ()
    +#define EXFUN(name, proto)		name()
    +#define DEFUN(name, arglist, args)	name arglist args;
    +#define DEFUN_VOID(name)		name()
    +#define AND		;
    +#define DOTS
    +#define NOARGS
    +#endif /* ! IN_GCC */
    +
    +#endif	/* ANSI C.  */
    +
    +/* Define macros for some gcc attributes.  This permits us to use the
    +   macros freely, and know that they will come into play for the
    +   version of gcc in which they are supported.  */
    +
    +#if (GCC_VERSION < 2007)
    +# define __attribute__(x)
    +#endif
    +
    +/* Attribute __malloc__ on functions was valid as of gcc 2.96. */
    +#ifndef ATTRIBUTE_MALLOC
    +# if (GCC_VERSION >= 2096)
    +#  define ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
    +# else
    +#  define ATTRIBUTE_MALLOC
    +# endif /* GNUC >= 2.96 */
    +#endif /* ATTRIBUTE_MALLOC */
    +
    +/* Attributes on labels were valid as of gcc 2.93 and g++ 4.5.  For
    +   g++ an attribute on a label must be followed by a semicolon.  */
    +#ifndef ATTRIBUTE_UNUSED_LABEL
    +# ifndef __cplusplus
    +#  if GCC_VERSION >= 2093
    +#   define ATTRIBUTE_UNUSED_LABEL ATTRIBUTE_UNUSED
    +#  else
    +#   define ATTRIBUTE_UNUSED_LABEL
    +#  endif
    +# else
    +#  if GCC_VERSION >= 4005
    +#   define ATTRIBUTE_UNUSED_LABEL ATTRIBUTE_UNUSED ;
    +#  else
    +#   define ATTRIBUTE_UNUSED_LABEL
    +#  endif
    +# endif
    +#endif
    +
    +/* Similarly to ARG_UNUSED below.  Prior to GCC 3.4, the C++ frontend
    +   couldn't parse attributes placed after the identifier name, and now
    +   the entire compiler is built with C++.  */
    +#ifndef ATTRIBUTE_UNUSED
    +#if GCC_VERSION >= 3004
    +#  define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
    +#else
    +#define ATTRIBUTE_UNUSED
    +#endif
    +#endif /* ATTRIBUTE_UNUSED */
    +
    +/* Before GCC 3.4, the C++ frontend couldn't parse attributes placed after the
    +   identifier name.  */
    +#if ! defined(__cplusplus) || (GCC_VERSION >= 3004)
    +# define ARG_UNUSED(NAME) NAME ATTRIBUTE_UNUSED
    +#else /* !__cplusplus || GNUC >= 3.4 */
    +# define ARG_UNUSED(NAME) NAME
    +#endif /* !__cplusplus || GNUC >= 3.4 */
    +
    +#ifndef ATTRIBUTE_NORETURN
    +#define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__))
    +#endif /* ATTRIBUTE_NORETURN */
    +
    +/* Attribute `nonnull' was valid as of gcc 3.3.  */
    +#ifndef ATTRIBUTE_NONNULL
    +# if (GCC_VERSION >= 3003)
    +#  define ATTRIBUTE_NONNULL(m) __attribute__ ((__nonnull__ (m)))
    +# else
    +#  define ATTRIBUTE_NONNULL(m)
    +# endif /* GNUC >= 3.3 */
    +#endif /* ATTRIBUTE_NONNULL */
    +
    +/* Attribute `pure' was valid as of gcc 3.0.  */
    +#ifndef ATTRIBUTE_PURE
    +# if (GCC_VERSION >= 3000)
    +#  define ATTRIBUTE_PURE __attribute__ ((__pure__))
    +# else
    +#  define ATTRIBUTE_PURE
    +# endif /* GNUC >= 3.0 */
    +#endif /* ATTRIBUTE_PURE */
    +
    +/* Use ATTRIBUTE_PRINTF when the format specifier must not be NULL.
    +   This was the case for the `printf' format attribute by itself
    +   before GCC 3.3, but as of 3.3 we need to add the `nonnull'
    +   attribute to retain this behavior.  */
    +#ifndef ATTRIBUTE_PRINTF
    +#define ATTRIBUTE_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n))) ATTRIBUTE_NONNULL(m)
    +#define ATTRIBUTE_PRINTF_1 ATTRIBUTE_PRINTF(1, 2)
    +#define ATTRIBUTE_PRINTF_2 ATTRIBUTE_PRINTF(2, 3)
    +#define ATTRIBUTE_PRINTF_3 ATTRIBUTE_PRINTF(3, 4)
    +#define ATTRIBUTE_PRINTF_4 ATTRIBUTE_PRINTF(4, 5)
    +#define ATTRIBUTE_PRINTF_5 ATTRIBUTE_PRINTF(5, 6)
    +#endif /* ATTRIBUTE_PRINTF */
    +
    +/* Use ATTRIBUTE_FPTR_PRINTF when the format attribute is to be set on
    +   a function pointer.  Format attributes were allowed on function
    +   pointers as of gcc 3.1.  */
    +#ifndef ATTRIBUTE_FPTR_PRINTF
    +# if (GCC_VERSION >= 3001)
    +#  define ATTRIBUTE_FPTR_PRINTF(m, n) ATTRIBUTE_PRINTF(m, n)
    +# else
    +#  define ATTRIBUTE_FPTR_PRINTF(m, n)
    +# endif /* GNUC >= 3.1 */
    +# define ATTRIBUTE_FPTR_PRINTF_1 ATTRIBUTE_FPTR_PRINTF(1, 2)
    +# define ATTRIBUTE_FPTR_PRINTF_2 ATTRIBUTE_FPTR_PRINTF(2, 3)
    +# define ATTRIBUTE_FPTR_PRINTF_3 ATTRIBUTE_FPTR_PRINTF(3, 4)
    +# define ATTRIBUTE_FPTR_PRINTF_4 ATTRIBUTE_FPTR_PRINTF(4, 5)
    +# define ATTRIBUTE_FPTR_PRINTF_5 ATTRIBUTE_FPTR_PRINTF(5, 6)
    +#endif /* ATTRIBUTE_FPTR_PRINTF */
    +
    +/* Use ATTRIBUTE_NULL_PRINTF when the format specifier may be NULL.  A
    +   NULL format specifier was allowed as of gcc 3.3.  */
    +#ifndef ATTRIBUTE_NULL_PRINTF
    +# if (GCC_VERSION >= 3003)
    +#  define ATTRIBUTE_NULL_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n)))
    +# else
    +#  define ATTRIBUTE_NULL_PRINTF(m, n)
    +# endif /* GNUC >= 3.3 */
    +# define ATTRIBUTE_NULL_PRINTF_1 ATTRIBUTE_NULL_PRINTF(1, 2)
    +# define ATTRIBUTE_NULL_PRINTF_2 ATTRIBUTE_NULL_PRINTF(2, 3)
    +# define ATTRIBUTE_NULL_PRINTF_3 ATTRIBUTE_NULL_PRINTF(3, 4)
    +# define ATTRIBUTE_NULL_PRINTF_4 ATTRIBUTE_NULL_PRINTF(4, 5)
    +# define ATTRIBUTE_NULL_PRINTF_5 ATTRIBUTE_NULL_PRINTF(5, 6)
    +#endif /* ATTRIBUTE_NULL_PRINTF */
    +
    +/* Attribute `sentinel' was valid as of gcc 3.5.  */
    +#ifndef ATTRIBUTE_SENTINEL
    +# if (GCC_VERSION >= 3005)
    +#  define ATTRIBUTE_SENTINEL __attribute__ ((__sentinel__))
    +# else
    +#  define ATTRIBUTE_SENTINEL
    +# endif /* GNUC >= 3.5 */
    +#endif /* ATTRIBUTE_SENTINEL */
    +
    +
    +#ifndef ATTRIBUTE_ALIGNED_ALIGNOF
    +# if (GCC_VERSION >= 3000)
    +#  define ATTRIBUTE_ALIGNED_ALIGNOF(m) __attribute__ ((__aligned__ (__alignof__ (m))))
    +# else
    +#  define ATTRIBUTE_ALIGNED_ALIGNOF(m)
    +# endif /* GNUC >= 3.0 */
    +#endif /* ATTRIBUTE_ALIGNED_ALIGNOF */
    +
    +/* Useful for structures whose layout must much some binary specification
    +   regardless of the alignment and padding qualities of the compiler.  */
    +#ifndef ATTRIBUTE_PACKED
    +# define ATTRIBUTE_PACKED __attribute__ ((packed))
    +#endif
    +
    +/* Attribute `hot' and `cold' was valid as of gcc 4.3.  */
    +#ifndef ATTRIBUTE_COLD
    +# if (GCC_VERSION >= 4003)
    +#  define ATTRIBUTE_COLD __attribute__ ((__cold__))
    +# else
    +#  define ATTRIBUTE_COLD
    +# endif /* GNUC >= 4.3 */
    +#endif /* ATTRIBUTE_COLD */
    +#ifndef ATTRIBUTE_HOT
    +# if (GCC_VERSION >= 4003)
    +#  define ATTRIBUTE_HOT __attribute__ ((__hot__))
    +# else
    +#  define ATTRIBUTE_HOT
    +# endif /* GNUC >= 4.3 */
    +#endif /* ATTRIBUTE_HOT */
    +
    +/* We use __extension__ in some places to suppress -pedantic warnings
    +   about GCC extensions.  This feature didn't work properly before
    +   gcc 2.8.  */
    +#if GCC_VERSION < 2008
    +#define __extension__
    +#endif
    +
    +/* This is used to declare a const variable which should be visible
    +   outside of the current compilation unit.  Use it as
    +     EXPORTED_CONST int i = 1;
    +   This is because the semantics of const are different in C and C++.
    +   "extern const" is permitted in C but it looks strange, and gcc
    +   warns about it when -Wc++-compat is not used.  */
    +#ifdef __cplusplus
    +#define EXPORTED_CONST extern const
    +#else
    +#define EXPORTED_CONST const
    +#endif
    +
    +/* Be conservative and only use enum bitfields with C++ or GCC.
    +   FIXME: provide a complete autoconf test for buggy enum bitfields.  */
    +
    +#ifdef __cplusplus
    +#define ENUM_BITFIELD(TYPE) enum TYPE
    +#elif (GCC_VERSION > 2000)
    +#define ENUM_BITFIELD(TYPE) __extension__ enum TYPE
    +#else
    +#define ENUM_BITFIELD(TYPE) unsigned int
    +#endif
    +
    +#ifdef __cplusplus
    +}
    +#endif
    +
    +#endif	/* ansidecl.h	*/
    
  • GPL/DemanglerGnu/src/demangler_gnu/headers/cp-demangle.h+173 0 added
    @@ -0,0 +1,173 @@
    +/* ###
    + * IP: GPL 3 Linking Permitted
    + * REVIEWED: YES
    + */
    +/* Internal demangler interface for g++ V3 ABI.
    +   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2010
    +   Free Software Foundation, Inc.
    +   Written by Ian Lance Taylor <ian@wasabisystems.com>.
    +
    +   This file is part of the libiberty library, which is part of GCC.
    +
    +   This file 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.
    +
    +   In addition to the permissions in the GNU General Public License, the
    +   Free Software Foundation gives you unlimited permission to link the
    +   compiled version of this file into combinations with other programs,
    +   and to distribute those combinations without any restriction coming
    +   from the use of this file.  (The General Public License restrictions
    +   do apply in other respects; for example, they cover modification of
    +   the file, and distribution when not linked into a combined
    +   executable.)
    +
    +   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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. 
    +*/
    +
    +/* This file provides some definitions shared by cp-demangle.c and
    +   cp-demint.c.  It should not be included by any other files.  */
    +
    +/* Information we keep for operators.  */
    +
    +struct demangle_operator_info
    +{
    +  /* Mangled name.  */
    +  const char *code;
    +  /* Real name.  */
    +  const char *name;
    +  /* Length of real name.  */
    +  int len;
    +  /* Number of arguments.  */
    +  int args;
    +};
    +
    +/* How to print the value of a builtin type.  */
    +
    +enum d_builtin_type_print
    +{
    +  /* Print as (type)val.  */
    +  D_PRINT_DEFAULT,
    +  /* Print as integer.  */
    +  D_PRINT_INT,
    +  /* Print as unsigned integer, with trailing "u".  */
    +  D_PRINT_UNSIGNED,
    +  /* Print as long, with trailing "l".  */
    +  D_PRINT_LONG,
    +  /* Print as unsigned long, with trailing "ul".  */
    +  D_PRINT_UNSIGNED_LONG,
    +  /* Print as long long, with trailing "ll".  */
    +  D_PRINT_LONG_LONG,
    +  /* Print as unsigned long long, with trailing "ull".  */
    +  D_PRINT_UNSIGNED_LONG_LONG,
    +  /* Print as bool.  */
    +  D_PRINT_BOOL,
    +  /* Print as float--put value in square brackets.  */
    +  D_PRINT_FLOAT,
    +  /* Print in usual way, but here to detect void.  */
    +  D_PRINT_VOID
    +};
    +
    +/* Information we keep for a builtin type.  */
    +
    +struct demangle_builtin_type_info
    +{
    +  /* Type name.  */
    +  const char *name;
    +  /* Length of type name.  */
    +  int len;
    +  /* Type name when using Java.  */
    +  const char *java_name;
    +  /* Length of java name.  */
    +  int java_len;
    +  /* How to print a value of this type.  */
    +  enum d_builtin_type_print print;
    +};
    +
    +/* The information structure we pass around.  */
    +
    +struct d_info
    +{
    +  /* The string we are demangling.  */
    +  const char *s;
    +  /* The end of the string we are demangling.  */
    +  const char *send;
    +  /* The options passed to the demangler.  */
    +  int options;
    +  /* The next character in the string to consider.  */
    +  const char *n;
    +  /* The array of components.  */
    +  struct demangle_component *comps;
    +  /* The index of the next available component.  */
    +  int next_comp;
    +  /* The number of available component structures.  */
    +  int num_comps;
    +  /* The array of substitutions.  */
    +  struct demangle_component **subs;
    +  /* The index of the next substitution.  */
    +  int next_sub;
    +  /* The number of available entries in the subs array.  */
    +  int num_subs;
    +  /* The number of substitutions which we actually made from the subs
    +     array, plus the number of template parameter references we
    +     saw.  */
    +  int did_subs;
    +  /* The last name we saw, for constructors and destructors.  */
    +  struct demangle_component *last_name;
    +  /* A running total of the length of large expansions from the
    +     mangled name to the demangled name, such as standard
    +     substitutions and builtin types.  */
    +  int expansion;
    +};
    +
    +/* To avoid running past the ending '\0', don't:
    +   - call d_peek_next_char if d_peek_char returned '\0'
    +   - call d_advance with an 'i' that is too large
    +   - call d_check_char(di, '\0')
    +   Everything else is safe.  */
    +#define d_peek_char(di) (*((di)->n))
    +#define d_peek_next_char(di) ((di)->n[1])
    +#define d_advance(di, i) ((di)->n += (i))
    +#define d_check_char(di, c) (d_peek_char(di) == c ? ((di)->n++, 1) : 0)
    +#define d_next_char(di) (d_peek_char(di) == '\0' ? '\0' : *((di)->n++))
    +#define d_str(di) ((di)->n)
    +
    +/* Functions and arrays in cp-demangle.c which are referenced by
    +   functions in cp-demint.c.  */
    +#ifdef IN_GLIBCPP_V3
    +#define CP_STATIC_IF_GLIBCPP_V3 static
    +#else
    +#define CP_STATIC_IF_GLIBCPP_V3 extern
    +#endif
    +
    +#ifndef IN_GLIBCPP_V3
    +extern const struct demangle_operator_info cplus_demangle_operators[];
    +#endif
    +
    +#define D_BUILTIN_TYPE_COUNT (33)
    +
    +CP_STATIC_IF_GLIBCPP_V3
    +const struct demangle_builtin_type_info
    +cplus_demangle_builtin_types[D_BUILTIN_TYPE_COUNT];
    +
    +CP_STATIC_IF_GLIBCPP_V3
    +struct demangle_component *
    +cplus_demangle_mangled_name (struct d_info *, int);
    +
    +CP_STATIC_IF_GLIBCPP_V3
    +struct demangle_component *
    +cplus_demangle_type (struct d_info *);
    +
    +extern void
    +cplus_demangle_init_info (const char *, int, size_t, struct d_info *);
    +
    +/* cp-demangle.c needs to define this a little differently */
    +#undef CP_STATIC_IF_GLIBCPP_V3
    
  • GPL/DemanglerGnu/src/demangler_gnu/headers/demangle.h+675 0 added
    @@ -0,0 +1,675 @@
    +/* ###
    + * IP: LGPL 3.0
    + * REVIEWED: YES
    + */
    +/* Defs for interface to demanglers.
    +   Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002,
    +   2003, 2004, 2005, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
    +   
    +   This program is free software; you can redistribute it and/or
    +   modify it under the terms of the GNU Library General Public License
    +   as published by the Free Software Foundation; either version 2, or
    +   (at your option) any later version.
    +
    +   In addition to the permissions in the GNU Library General Public
    +   License, the Free Software Foundation gives you unlimited
    +   permission to link the compiled version of this file into
    +   combinations with other programs, and to distribute those
    +   combinations without any restriction coming from the use of this
    +   file.  (The Library Public License restrictions do apply in other
    +   respects; for example, they cover modification of the file, and
    +   distribution when not linked into a combined executable.)
    +
    +   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
    +   Library General Public License for more details.
    +
    +   You should have received a copy of the GNU Library General Public
    +   License along with this program; if not, write to the Free Software
    +   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
    +   02110-1301, USA.  */
    +
    +
    +#if !defined (DEMANGLE_H)
    +#define DEMANGLE_H
    +
    +#include "libiberty.h"
    +
    +#ifdef __cplusplus
    +extern "C" {
    +#endif /* __cplusplus */
    +
    +/* Options passed to cplus_demangle (in 2nd parameter). */
    +
    +#define DMGL_NO_OPTS	 0		/* For readability... */
    +#define DMGL_PARAMS	 (1 << 0)	/* Include function args */
    +#define DMGL_ANSI	 (1 << 1)	/* Include const, volatile, etc */
    +#define DMGL_JAVA	 (1 << 2)	/* Demangle as Java rather than C++. */
    +#define DMGL_VERBOSE	 (1 << 3)	/* Include implementation details.  */
    +#define DMGL_TYPES	 (1 << 4)	/* Also try to demangle type encodings.  */
    +#define DMGL_RET_POSTFIX (1 << 5)       /* Print function return types (when
    +					   present) after function signature.
    +					   It applies only to the toplevel
    +					   function type.  */
    +#define DMGL_RET_DROP	 (1 << 6)       /* Suppress printing function return
    +					   types, even if present.  It applies
    +					   only to the toplevel function type.
    +					   */
    +
    +#define DMGL_AUTO	 (1 << 8)
    +#define DMGL_GNU	 (1 << 9)
    +#define DMGL_LUCID	 (1 << 10)
    +#define DMGL_ARM	 (1 << 11)
    +#define DMGL_HP 	 (1 << 12)       /* For the HP aCC compiler;
    +                                            same as ARM except for
    +                                            template arguments, etc. */
    +#define DMGL_EDG	 (1 << 13)
    +#define DMGL_GNU_V3	 (1 << 14)
    +#define DMGL_GNAT	 (1 << 15)
    +
    +/* If none of these are set, use 'current_demangling_style' as the default. */
    +#define DMGL_STYLE_MASK (DMGL_AUTO|DMGL_GNU|DMGL_LUCID|DMGL_ARM|DMGL_HP|DMGL_EDG|DMGL_GNU_V3|DMGL_JAVA|DMGL_GNAT)
    +
    +/* Enumeration of possible demangling styles.
    +
    +   Lucid and ARM styles are still kept logically distinct, even though
    +   they now both behave identically.  The resulting style is actual the
    +   union of both.  I.E. either style recognizes both "__pt__" and "__rf__"
    +   for operator "->", even though the first is lucid style and the second
    +   is ARM style. (FIXME?) */
    +
    +extern enum demangling_styles
    +{
    +  no_demangling = -1,
    +  unknown_demangling = 0,
    +  auto_demangling = DMGL_AUTO,
    +  gnu_demangling = DMGL_GNU,
    +  lucid_demangling = DMGL_LUCID,
    +  arm_demangling = DMGL_ARM,
    +  hp_demangling = DMGL_HP,
    +  edg_demangling = DMGL_EDG,
    +  gnu_v3_demangling = DMGL_GNU_V3,
    +  java_demangling = DMGL_JAVA,
    +  gnat_demangling = DMGL_GNAT
    +} current_demangling_style;
    +
    +/* Define string names for the various demangling styles. */
    +
    +#define NO_DEMANGLING_STYLE_STRING            "none"
    +#define AUTO_DEMANGLING_STYLE_STRING	      "auto"
    +#define GNU_DEMANGLING_STYLE_STRING    	      "gnu"
    +#define LUCID_DEMANGLING_STYLE_STRING	      "lucid"
    +#define ARM_DEMANGLING_STYLE_STRING	      "arm"
    +#define HP_DEMANGLING_STYLE_STRING	      "hp"
    +#define EDG_DEMANGLING_STYLE_STRING	      "edg"
    +#define GNU_V3_DEMANGLING_STYLE_STRING        "gnu-v3"
    +#define JAVA_DEMANGLING_STYLE_STRING          "java"
    +#define GNAT_DEMANGLING_STYLE_STRING          "gnat"
    +
    +/* Some macros to test what demangling style is active. */
    +
    +#define CURRENT_DEMANGLING_STYLE current_demangling_style
    +#define AUTO_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_AUTO)
    +#define GNU_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_GNU)
    +#define LUCID_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_LUCID)
    +#define ARM_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_ARM)
    +#define HP_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_HP)
    +#define EDG_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_EDG)
    +#define GNU_V3_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_GNU_V3)
    +#define JAVA_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_JAVA)
    +#define GNAT_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_GNAT)
    +
    +/* Provide information about the available demangle styles. This code is
    +   pulled from gdb into libiberty because it is useful to binutils also.  */
    +
    +extern const struct demangler_engine
    +{
    +  const char *const demangling_style_name;
    +  const enum demangling_styles demangling_style;
    +  const char *const demangling_style_doc;
    +} libiberty_demanglers[];
    +
    +extern char *
    +cplus_demangle (const char *mangled, int options);
    +
    +extern int
    +cplus_demangle_opname (const char *opname, char *result, int options);
    +
    +extern const char *
    +cplus_mangle_opname (const char *opname, int options);
    +
    +/* Note: This sets global state.  FIXME if you care about multi-threading. */
    +
    +extern void
    +set_cplus_marker_for_demangling (int ch);
    +
    +extern enum demangling_styles 
    +cplus_demangle_set_style (enum demangling_styles style);
    +
    +extern enum demangling_styles 
    +cplus_demangle_name_to_style (const char *name);
    +
    +/* Callback typedef for allocation-less demangler interfaces. */
    +typedef void (*demangle_callbackref) (const char *, size_t, void *);
    +
    +/* V3 ABI demangling entry points, defined in cp-demangle.c.  Callback
    +   variants return non-zero on success, zero on error.  char* variants
    +   return a string allocated by malloc on success, NULL on error.  */
    +extern int
    +cplus_demangle_v3_callback (const char *mangled, int options,
    +                            demangle_callbackref callback, void *opaque);
    +
    +extern char*
    +cplus_demangle_v3 (const char *mangled, int options);
    +
    +extern int
    +java_demangle_v3_callback (const char *mangled,
    +                           demangle_callbackref callback, void *opaque);
    +
    +extern char*
    +java_demangle_v3 (const char *mangled);
    +
    +char *
    +ada_demangle (const char *mangled, int options);
    +
    +enum gnu_v3_ctor_kinds {
    +  gnu_v3_complete_object_ctor = 1,
    +  gnu_v3_base_object_ctor,
    +  gnu_v3_complete_object_allocating_ctor,
    +  gnu_v3_object_ctor_group
    +};
    +
    +/* Return non-zero iff NAME is the mangled form of a constructor name
    +   in the G++ V3 ABI demangling style.  Specifically, return an `enum
    +   gnu_v3_ctor_kinds' value indicating what kind of constructor
    +   it is.  */
    +extern enum gnu_v3_ctor_kinds
    +	is_gnu_v3_mangled_ctor (const char *name);
    +
    +
    +enum gnu_v3_dtor_kinds {
    +  gnu_v3_deleting_dtor = 1,
    +  gnu_v3_complete_object_dtor,
    +  gnu_v3_base_object_dtor,
    +  gnu_v3_object_dtor_group
    +};
    +
    +/* Return non-zero iff NAME is the mangled form of a destructor name
    +   in the G++ V3 ABI demangling style.  Specifically, return an `enum
    +   gnu_v3_dtor_kinds' value, indicating what kind of destructor
    +   it is.  */
    +extern enum gnu_v3_dtor_kinds
    +	is_gnu_v3_mangled_dtor (const char *name);
    +
    +/* The V3 demangler works in two passes.  The first pass builds a tree
    +   representation of the mangled name, and the second pass turns the
    +   tree representation into a demangled string.  Here we define an
    +   interface to permit a caller to build their own tree
    +   representation, which they can pass to the demangler to get a
    +   demangled string.  This can be used to canonicalize user input into
    +   something which the demangler might output.  It could also be used
    +   by other demanglers in the future.  */
    +
    +/* These are the component types which may be found in the tree.  Many
    +   component types have one or two subtrees, referred to as left and
    +   right (a component type with only one subtree puts it in the left
    +   subtree).  */
    +
    +enum demangle_component_type
    +{
    +  /* A name, with a length and a pointer to a string.  */
    +  DEMANGLE_COMPONENT_NAME,
    +  /* A qualified name.  The left subtree is a class or namespace or
    +     some such thing, and the right subtree is a name qualified by
    +     that class.  */
    +  DEMANGLE_COMPONENT_QUAL_NAME,
    +  /* A local name.  The left subtree describes a function, and the
    +     right subtree is a name which is local to that function.  */
    +  DEMANGLE_COMPONENT_LOCAL_NAME,
    +  /* A typed name.  The left subtree is a name, and the right subtree
    +     describes that name as a function.  */
    +  DEMANGLE_COMPONENT_TYPED_NAME,
    +  /* A template.  The left subtree is a template name, and the right
    +     subtree is a template argument list.  */
    +  DEMANGLE_COMPONENT_TEMPLATE,
    +  /* A template parameter.  This holds a number, which is the template
    +     parameter index.  */
    +  DEMANGLE_COMPONENT_TEMPLATE_PARAM,
    +  /* A function parameter.  This holds a number, which is the index.  */
    +  DEMANGLE_COMPONENT_FUNCTION_PARAM,
    +  /* A constructor.  This holds a name and the kind of
    +     constructor.  */
    +  DEMANGLE_COMPONENT_CTOR,
    +  /* A destructor.  This holds a name and the kind of destructor.  */
    +  DEMANGLE_COMPONENT_DTOR,
    +  /* A vtable.  This has one subtree, the type for which this is a
    +     vtable.  */
    +  DEMANGLE_COMPONENT_VTABLE,
    +  /* A VTT structure.  This has one subtree, the type for which this
    +     is a VTT.  */
    +  DEMANGLE_COMPONENT_VTT,
    +  /* A construction vtable.  The left subtree is the type for which
    +     this is a vtable, and the right subtree is the derived type for
    +     which this vtable is built.  */
    +  DEMANGLE_COMPONENT_CONSTRUCTION_VTABLE,
    +  /* A typeinfo structure.  This has one subtree, the type for which
    +     this is the tpeinfo structure.  */
    +  DEMANGLE_COMPONENT_TYPEINFO,
    +  /* A typeinfo name.  This has one subtree, the type for which this
    +     is the typeinfo name.  */
    +  DEMANGLE_COMPONENT_TYPEINFO_NAME,
    +  /* A typeinfo function.  This has one subtree, the type for which
    +     this is the tpyeinfo function.  */
    +  DEMANGLE_COMPONENT_TYPEINFO_FN,
    +  /* A thunk.  This has one subtree, the name for which this is a
    +     thunk.  */
    +  DEMANGLE_COMPONENT_THUNK,
    +  /* A virtual thunk.  This has one subtree, the name for which this
    +     is a virtual thunk.  */
    +  DEMANGLE_COMPONENT_VIRTUAL_THUNK,
    +  /* A covariant thunk.  This has one subtree, the name for which this
    +     is a covariant thunk.  */
    +  DEMANGLE_COMPONENT_COVARIANT_THUNK,
    +  /* A Java class.  This has one subtree, the type.  */
    +  DEMANGLE_COMPONENT_JAVA_CLASS,
    +  /* A guard variable.  This has one subtree, the name for which this
    +     is a guard variable.  */
    +  DEMANGLE_COMPONENT_GUARD,
    +  /* The init and wrapper functions for C++11 thread_local variables.  */
    +  DEMANGLE_COMPONENT_TLS_INIT,
    +  DEMANGLE_COMPONENT_TLS_WRAPPER,
    +  /* A reference temporary.  This has one subtree, the name for which
    +     this is a temporary.  */
    +  DEMANGLE_COMPONENT_REFTEMP,
    +  /* A hidden alias.  This has one subtree, the encoding for which it
    +     is providing alternative linkage.  */
    +  DEMANGLE_COMPONENT_HIDDEN_ALIAS,
    +  /* A standard substitution.  This holds the name of the
    +     substitution.  */
    +  DEMANGLE_COMPONENT_SUB_STD,
    +  /* The restrict qualifier.  The one subtree is the type which is
    +     being qualified.  */
    +  DEMANGLE_COMPONENT_RESTRICT,
    +  /* The volatile qualifier.  The one subtree is the type which is
    +     being qualified.  */
    +  DEMANGLE_COMPONENT_VOLATILE,
    +  /* The const qualifier.  The one subtree is the type which is being
    +     qualified.  */
    +  DEMANGLE_COMPONENT_CONST,
    +  /* The restrict qualifier modifying a member function.  The one
    +     subtree is the type which is being qualified.  */
    +  DEMANGLE_COMPONENT_RESTRICT_THIS,
    +  /* The volatile qualifier modifying a member function.  The one
    +     subtree is the type which is being qualified.  */
    +  DEMANGLE_COMPONENT_VOLATILE_THIS,
    +  /* The const qualifier modifying a member function.  The one subtree
    +     is the type which is being qualified.  */
    +  DEMANGLE_COMPONENT_CONST_THIS,
    +  /* C++11 A reference modifying a member function.  The one subtree is the
    +     type which is being referenced.  */
    +  DEMANGLE_COMPONENT_REFERENCE_THIS,
    +  /* C++11: An rvalue reference modifying a member function.  The one
    +     subtree is the type which is being referenced.  */
    +  DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS,
    +  /* A vendor qualifier.  The left subtree is the type which is being
    +     qualified, and the right subtree is the name of the
    +     qualifier.  */
    +  DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL,
    +  /* A pointer.  The one subtree is the type which is being pointed
    +     to.  */
    +  DEMANGLE_COMPONENT_POINTER,
    +  /* A reference.  The one subtree is the type which is being
    +     referenced.  */
    +  DEMANGLE_COMPONENT_REFERENCE,
    +  /* C++0x: An rvalue reference.  The one subtree is the type which is
    +     being referenced.  */
    +  DEMANGLE_COMPONENT_RVALUE_REFERENCE,
    +  /* A complex type.  The one subtree is the base type.  */
    +  DEMANGLE_COMPONENT_COMPLEX,
    +  /* An imaginary type.  The one subtree is the base type.  */
    +  DEMANGLE_COMPONENT_IMAGINARY,
    +  /* A builtin type.  This holds the builtin type information.  */
    +  DEMANGLE_COMPONENT_BUILTIN_TYPE,
    +  /* A vendor's builtin type.  This holds the name of the type.  */
    +  DEMANGLE_COMPONENT_VENDOR_TYPE,
    +  /* A function type.  The left subtree is the return type.  The right
    +     subtree is a list of ARGLIST nodes.  Either or both may be
    +     NULL.  */
    +  DEMANGLE_COMPONENT_FUNCTION_TYPE,
    +  /* An array type.  The left subtree is the dimension, which may be
    +     NULL, or a string (represented as DEMANGLE_COMPONENT_NAME), or an
    +     expression.  The right subtree is the element type.  */
    +  DEMANGLE_COMPONENT_ARRAY_TYPE,
    +  /* A pointer to member type.  The left subtree is the class type,
    +     and the right subtree is the member type.  CV-qualifiers appear
    +     on the latter.  */
    +  DEMANGLE_COMPONENT_PTRMEM_TYPE,
    +  /* A fixed-point type.  */
    +  DEMANGLE_COMPONENT_FIXED_TYPE,
    +  /* A vector type.  The left subtree is the number of elements,
    +     the right subtree is the element type.  */
    +  DEMANGLE_COMPONENT_VECTOR_TYPE,
    +  /* An argument list.  The left subtree is the current argument, and
    +     the right subtree is either NULL or another ARGLIST node.  */
    +  DEMANGLE_COMPONENT_ARGLIST,
    +  /* A template argument list.  The left subtree is the current
    +     template argument, and the right subtree is either NULL or
    +     another TEMPLATE_ARGLIST node.  */
    +  DEMANGLE_COMPONENT_TEMPLATE_ARGLIST,
    +  /* An initializer list.  The left subtree is either an explicit type or
    +     NULL, and the right subtree is a DEMANGLE_COMPONENT_ARGLIST.  */
    +  DEMANGLE_COMPONENT_INITIALIZER_LIST,
    +  /* An operator.  This holds information about a standard
    +     operator.  */
    +  DEMANGLE_COMPONENT_OPERATOR,
    +  /* An extended operator.  This holds the number of arguments, and
    +     the name of the extended operator.  */
    +  DEMANGLE_COMPONENT_EXTENDED_OPERATOR,
    +  /* A typecast, represented as a unary operator.  The one subtree is
    +     the type to which the argument should be cast.  */
    +  DEMANGLE_COMPONENT_CAST,
    +  /* A nullary expression.  The left subtree is the operator.  */
    +  DEMANGLE_COMPONENT_NULLARY,
    +  /* A unary expression.  The left subtree is the operator, and the
    +     right subtree is the single argument.  */
    +  DEMANGLE_COMPONENT_UNARY,
    +  /* A binary expression.  The left subtree is the operator, and the
    +     right subtree is a BINARY_ARGS.  */
    +  DEMANGLE_COMPONENT_BINARY,
    +  /* Arguments to a binary expression.  The left subtree is the first
    +     argument, and the right subtree is the second argument.  */
    +  DEMANGLE_COMPONENT_BINARY_ARGS,
    +  /* A trinary expression.  The left subtree is the operator, and the
    +     right subtree is a TRINARY_ARG1.  */
    +  DEMANGLE_COMPONENT_TRINARY,
    +  /* Arguments to a trinary expression.  The left subtree is the first
    +     argument, and the right subtree is a TRINARY_ARG2.  */
    +  DEMANGLE_COMPONENT_TRINARY_ARG1,
    +  /* More arguments to a trinary expression.  The left subtree is the
    +     second argument, and the right subtree is the third argument.  */
    +  DEMANGLE_COMPONENT_TRINARY_ARG2,
    +  /* A literal.  The left subtree is the type, and the right subtree
    +     is the value, represented as a DEMANGLE_COMPONENT_NAME.  */
    +  DEMANGLE_COMPONENT_LITERAL,
    +  /* A negative literal.  Like LITERAL, but the value is negated.
    +     This is a minor hack: the NAME used for LITERAL points directly
    +     to the mangled string, but since negative numbers are mangled
    +     using 'n' instead of '-', we want a way to indicate a negative
    +     number which involves neither modifying the mangled string nor
    +     allocating a new copy of the literal in memory.  */
    +  DEMANGLE_COMPONENT_LITERAL_NEG,
    +  /* A libgcj compiled resource.  The left subtree is the name of the
    +     resource.  */
    +  DEMANGLE_COMPONENT_JAVA_RESOURCE,
    +  /* A name formed by the concatenation of two parts.  The left
    +     subtree is the first part and the right subtree the second.  */
    +  DEMANGLE_COMPONENT_COMPOUND_NAME,
    +  /* A name formed by a single character.  */
    +  DEMANGLE_COMPONENT_CHARACTER,
    +  /* A number.  */
    +  DEMANGLE_COMPONENT_NUMBER,
    +  /* A decltype type.  */
    +  DEMANGLE_COMPONENT_DECLTYPE,
    +  /* Global constructors keyed to name.  */
    +  DEMANGLE_COMPONENT_GLOBAL_CONSTRUCTORS,
    +  /* Global destructors keyed to name.  */
    +  DEMANGLE_COMPONENT_GLOBAL_DESTRUCTORS,
    +  /* A lambda closure type.  */
    +  DEMANGLE_COMPONENT_LAMBDA,
    +  /* A default argument scope.  */
    +  DEMANGLE_COMPONENT_DEFAULT_ARG,
    +  /* An unnamed type.  */
    +  DEMANGLE_COMPONENT_UNNAMED_TYPE,
    +  /* A transactional clone.  This has one subtree, the encoding for
    +     which it is providing alternative linkage.  */
    +  DEMANGLE_COMPONENT_TRANSACTION_CLONE,
    +  /* A non-transactional clone entry point.  In the i386/x86_64 abi,
    +     the unmangled symbol of a tm_callable becomes a thunk and the
    +     non-transactional function version is mangled thus.  */
    +  DEMANGLE_COMPONENT_NONTRANSACTION_CLONE,
    +  /* A pack expansion.  */
    +  DEMANGLE_COMPONENT_PACK_EXPANSION,
    +  /* A name with an ABI tag.  */
    +  DEMANGLE_COMPONENT_TAGGED_NAME,
    +  /* A cloned function.  */
    +  DEMANGLE_COMPONENT_CLONE
    +};
    +
    +/* Types which are only used internally.  */
    +
    +struct demangle_operator_info;
    +struct demangle_builtin_type_info;
    +
    +/* A node in the tree representation is an instance of a struct
    +   demangle_component.  Note that the field names of the struct are
    +   not well protected against macros defined by the file including
    +   this one.  We can fix this if it ever becomes a problem.  */
    +
    +struct demangle_component
    +{
    +  /* The type of this component.  */
    +  enum demangle_component_type type;
    +
    +  union
    +  {
    +    /* For DEMANGLE_COMPONENT_NAME.  */
    +    struct
    +    {
    +      /* A pointer to the name (which need not NULL terminated) and
    +	 its length.  */
    +      const char *s;
    +      int len;
    +    } s_name;
    +
    +    /* For DEMANGLE_COMPONENT_OPERATOR.  */
    +    struct
    +    {
    +      /* Operator.  */
    +      const struct demangle_operator_info *op;
    +    } s_operator;
    +
    +    /* For DEMANGLE_COMPONENT_EXTENDED_OPERATOR.  */
    +    struct
    +    {
    +      /* Number of arguments.  */
    +      int args;
    +      /* Name.  */
    +      struct demangle_component *name;
    +    } s_extended_operator;
    +
    +    /* For DEMANGLE_COMPONENT_FIXED_TYPE.  */
    +    struct
    +    {
    +      /* The length, indicated by a C integer type name.  */
    +      struct demangle_component *length;
    +      /* _Accum or _Fract?  */
    +      short accum;
    +      /* Saturating or not?  */
    +      short sat;
    +    } s_fixed;
    +
    +    /* For DEMANGLE_COMPONENT_CTOR.  */
    +    struct
    +    {
    +      /* Kind of constructor.  */
    +      enum gnu_v3_ctor_kinds kind;
    +      /* Name.  */
    +      struct demangle_component *name;
    +    } s_ctor;
    +
    +    /* For DEMANGLE_COMPONENT_DTOR.  */
    +    struct
    +    {
    +      /* Kind of destructor.  */
    +      enum gnu_v3_dtor_kinds kind;
    +      /* Name.  */
    +      struct demangle_component *name;
    +    } s_dtor;
    +
    +    /* For DEMANGLE_COMPONENT_BUILTIN_TYPE.  */
    +    struct
    +    {
    +      /* Builtin type.  */
    +      const struct demangle_builtin_type_info *type;
    +    } s_builtin;
    +
    +    /* For DEMANGLE_COMPONENT_SUB_STD.  */
    +    struct
    +    {
    +      /* Standard substitution string.  */
    +      const char* string;
    +      /* Length of string.  */
    +      int len;
    +    } s_string;
    +
    +    /* For DEMANGLE_COMPONENT_*_PARAM.  */
    +    struct
    +    {
    +      /* Parameter index.  */
    +      long number;
    +    } s_number;
    +
    +    /* For DEMANGLE_COMPONENT_CHARACTER.  */
    +    struct
    +    {
    +      int character;
    +    } s_character;
    +
    +    /* For other types.  */
    +    struct
    +    {
    +      /* Left (or only) subtree.  */
    +      struct demangle_component *left;
    +      /* Right subtree.  */
    +      struct demangle_component *right;
    +    } s_binary;
    +
    +    struct
    +    {
    +      /* subtree, same place as d_left.  */
    +      struct demangle_component *sub;
    +      /* integer.  */
    +      int num;
    +    } s_unary_num;
    +
    +  } u;
    +};
    +
    +/* People building mangled trees are expected to allocate instances of
    +   struct demangle_component themselves.  They can then call one of
    +   the following functions to fill them in.  */
    +
    +/* Fill in most component types with a left subtree and a right
    +   subtree.  Returns non-zero on success, zero on failure, such as an
    +   unrecognized or inappropriate component type.  */
    +
    +extern int
    +cplus_demangle_fill_component (struct demangle_component *fill,
    +                               enum demangle_component_type,
    +                               struct demangle_component *left,
    +                               struct demangle_component *right);
    +
    +/* Fill in a DEMANGLE_COMPONENT_NAME.  Returns non-zero on success,
    +   zero for bad arguments.  */
    +
    +extern int
    +cplus_demangle_fill_name (struct demangle_component *fill,
    +                          const char *, int);
    +
    +/* Fill in a DEMANGLE_COMPONENT_BUILTIN_TYPE, using the name of the
    +   builtin type (e.g., "int", etc.).  Returns non-zero on success,
    +   zero if the type is not recognized.  */
    +
    +extern int
    +cplus_demangle_fill_builtin_type (struct demangle_component *fill,
    +                                  const char *type_name);
    +
    +/* Fill in a DEMANGLE_COMPONENT_OPERATOR, using the name of the
    +   operator and the number of arguments which it takes (the latter is
    +   used to disambiguate operators which can be both binary and unary,
    +   such as '-').  Returns non-zero on success, zero if the operator is
    +   not recognized.  */
    +
    +extern int
    +cplus_demangle_fill_operator (struct demangle_component *fill,
    +                              const char *opname, int args);
    +
    +/* Fill in a DEMANGLE_COMPONENT_EXTENDED_OPERATOR, providing the
    +   number of arguments and the name.  Returns non-zero on success,
    +   zero for bad arguments.  */
    +
    +extern int
    +cplus_demangle_fill_extended_operator (struct demangle_component *fill,
    +                                       int numargs,
    +                                       struct demangle_component *nm);
    +
    +/* Fill in a DEMANGLE_COMPONENT_CTOR.  Returns non-zero on success,
    +   zero for bad arguments.  */
    +
    +extern int
    +cplus_demangle_fill_ctor (struct demangle_component *fill,
    +                          enum gnu_v3_ctor_kinds kind,
    +                          struct demangle_component *name);
    +
    +/* Fill in a DEMANGLE_COMPONENT_DTOR.  Returns non-zero on success,
    +   zero for bad arguments.  */
    +
    +extern int
    +cplus_demangle_fill_dtor (struct demangle_component *fill,
    +                          enum gnu_v3_dtor_kinds kind,
    +                          struct demangle_component *name);
    +
    +/* This function translates a mangled name into a struct
    +   demangle_component tree.  The first argument is the mangled name.
    +   The second argument is DMGL_* options.  This returns a pointer to a
    +   tree on success, or NULL on failure.  On success, the third
    +   argument is set to a block of memory allocated by malloc.  This
    +   block should be passed to free when the tree is no longer
    +   needed.  */
    +
    +extern struct demangle_component *
    +cplus_demangle_v3_components (const char *mangled, int options, void **mem);
    +
    +/* This function takes a struct demangle_component tree and returns
    +   the corresponding demangled string.  The first argument is DMGL_*
    +   options.  The second is the tree to demangle.  The third is a guess
    +   at the length of the demangled string, used to initially allocate
    +   the return buffer.  The fourth is a pointer to a size_t.  On
    +   success, this function returns a buffer allocated by malloc(), and
    +   sets the size_t pointed to by the fourth argument to the size of
    +   the allocated buffer (not the length of the returned string).  On
    +   failure, this function returns NULL, and sets the size_t pointed to
    +   by the fourth argument to 0 for an invalid tree, or to 1 for a
    +   memory allocation error.  */
    +
    +extern char *
    +cplus_demangle_print (int options,
    +                      const struct demangle_component *tree,
    +                      int estimated_length,
    +                      size_t *p_allocated_size);
    +
    +/* This function takes a struct demangle_component tree and passes back
    +   a demangled string in one or more calls to a callback function.
    +   The first argument is DMGL_* options.  The second is the tree to
    +   demangle.  The third is a pointer to a callback function; on each call
    +   this receives an element of the demangled string, its length, and an
    +   opaque value.  The fourth is the opaque value passed to the callback.
    +   The callback is called once or more to return the full demangled
    +   string.  The demangled element string is always nul-terminated, though
    +   its length is also provided for convenience.  In contrast to
    +   cplus_demangle_print(), this function does not allocate heap memory
    +   to grow output strings (except perhaps where alloca() is implemented
    +   by malloc()), and so is normally safe for use where the heap has been
    +   corrupted.  On success, this function returns 1; on failure, 0.  */
    +
    +extern int
    +cplus_demangle_print_callback (int options,
    +                               const struct demangle_component *tree,
    +                               demangle_callbackref callback, void *opaque);
    +
    +#ifdef __cplusplus
    +}
    +#endif /* __cplusplus */
    +
    +#endif	/* DEMANGLE_H */
    
  • GPL/DemanglerGnu/src/demangler_gnu/headers/dyn-string.h+77 0 added
    @@ -0,0 +1,77 @@
    +/* ###
    + * IP: GPL 3
    + * REVIEWED: YES
    + */
    +/* An abstract string datatype.
    +   Copyright (C) 1998, 1999, 2000, 2002, 2004, 2005, 2009
    +   Free Software Foundation, Inc.
    +   Contributed by Mark Mitchell (mark@markmitchell.com).
    +
    +This file is part of GCC.
    +   
    +GCC 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, or (at your option)
    +any later version.
    +
    +GCC 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 GCC; see the file COPYING.  If not, write to
    +the Free Software Foundation, 51 Franklin Street - Fifth Floor,
    +Boston, MA 02110-1301, USA.  */
    +
    +#ifndef DYN_STRING_H
    +#define DYN_STRING_H
    +
    +#ifdef __cplusplus
    +extern "C" {
    +#endif
    +
    +typedef struct dyn_string
    +{
    +  int allocated;	/* The amount of space allocated for the string.  */
    +  int length;		/* The actual length of the string.  */
    +  char *s;		/* The string itself, NUL-terminated.  */
    +}* dyn_string_t;
    +
    +/* The length STR, in bytes, not including the terminating NUL.  */
    +#define dyn_string_length(STR)                                          \
    +  ((STR)->length)
    +
    +/* The NTBS in which the contents of STR are stored.  */
    +#define dyn_string_buf(STR)                                             \
    +  ((STR)->s)
    +
    +/* Compare DS1 to DS2 with strcmp.  */
    +#define dyn_string_compare(DS1, DS2)                                    \
    +  (strcmp ((DS1)->s, (DS2)->s))
    +
    +
    +extern int dyn_string_init (struct dyn_string *, int);
    +extern dyn_string_t dyn_string_new (int);
    +extern void dyn_string_delete (dyn_string_t);
    +extern char *dyn_string_release (dyn_string_t);
    +extern dyn_string_t dyn_string_resize (dyn_string_t, int);
    +extern void dyn_string_clear (dyn_string_t);
    +extern int dyn_string_copy (dyn_string_t, dyn_string_t);
    +extern int dyn_string_copy_cstr (dyn_string_t, const char *);
    +extern int dyn_string_prepend (dyn_string_t, dyn_string_t);
    +extern int dyn_string_prepend_cstr (dyn_string_t, const char *);
    +extern int dyn_string_insert (dyn_string_t, int, dyn_string_t);
    +extern int dyn_string_insert_cstr (dyn_string_t, int, const char *);
    +extern int dyn_string_insert_char (dyn_string_t, int, int);
    +extern int dyn_string_append (dyn_string_t, dyn_string_t);
    +extern int dyn_string_append_cstr (dyn_string_t, const char *);
    +extern int dyn_string_append_char (dyn_string_t, int);
    +extern int dyn_string_substring (dyn_string_t,  dyn_string_t, int, int);
    +extern int dyn_string_eq (dyn_string_t, dyn_string_t);
    +
    +#ifdef __cplusplus
    +}
    +#endif
    +
    +#endif /* !defined (DYN_STRING_H) */
    
  • GPL/DemanglerGnu/src/demangler_gnu/headers/getopt.h+148 0 added
    @@ -0,0 +1,148 @@
    +/* ###
    + * IP: GPL 3
    + * REVIEWED: YES
    + */
    +/* Declarations for getopt.
    +   Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998, 2000,
    +   2002 Free Software Foundation, Inc.
    +
    +   NOTE: The canonical source of this file is maintained with the GNU C Library.
    +   Bugs can be reported to bug-glibc@gnu.org.
    +
    +   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, 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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301,
    +   USA.  */
    +
    +#ifndef _GETOPT_H
    +#define _GETOPT_H 1
    +
    +#ifdef	__cplusplus
    +extern "C" {
    +#endif
    +
    +/* For communication from `getopt' to the caller.
    +   When `getopt' finds an option that takes an argument,
    +   the argument value is returned here.
    +   Also, when `ordering' is RETURN_IN_ORDER,
    +   each non-option ARGV-element is returned here.  */
    +
    +extern char *optarg;
    +
    +/* Index in ARGV of the next element to be scanned.
    +   This is used for communication to and from the caller
    +   and for communication between successive calls to `getopt'.
    +
    +   On entry to `getopt', zero means this is the first call; initialize.
    +
    +   When `getopt' returns -1, this is the index of the first of the
    +   non-option elements that the caller should itself scan.
    +
    +   Otherwise, `optind' communicates from one call to the next
    +   how much of ARGV has been scanned so far.  */
    +
    +extern int optind;
    +
    +/* Callers store zero here to inhibit the error message `getopt' prints
    +   for unrecognized options.  */
    +
    +extern int opterr;
    +
    +/* Set to an option character which was unrecognized.  */
    +
    +extern int optopt;
    +
    +/* Describe the long-named options requested by the application.
    +   The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
    +   of `struct option' terminated by an element containing a name which is
    +   zero.
    +
    +   The field `has_arg' is:
    +   no_argument		(or 0) if the option does not take an argument,
    +   required_argument	(or 1) if the option requires an argument,
    +   optional_argument 	(or 2) if the option takes an optional argument.
    +
    +   If the field `flag' is not NULL, it points to a variable that is set
    +   to the value given in the field `val' when the option is found, but
    +   left unchanged if the option is not found.
    +
    +   To have a long-named option do something other than set an `int' to
    +   a compiled-in constant, such as set a value from `optarg', set the
    +   option's `flag' field to zero and its `val' field to a nonzero
    +   value (the equivalent single-letter option character, if there is
    +   one).  For long options that have a zero `flag' field, `getopt'
    +   returns the contents of the `val' field.  */
    +
    +struct option
    +{
    +#if defined (__STDC__) && __STDC__
    +  const char *name;
    +#else
    +  char *name;
    +#endif
    +  /* has_arg can't be an enum because some compilers complain about
    +     type mismatches in all the code that assumes it is an int.  */
    +  int has_arg;
    +  int *flag;
    +  int val;
    +};
    +
    +/* Names for the values of the `has_arg' field of `struct option'.  */
    +
    +#define	no_argument		0
    +#define required_argument	1
    +#define optional_argument	2
    +
    +#if defined (__STDC__) && __STDC__
    +/* HAVE_DECL_* is a three-state macro: undefined, 0 or 1.  If it is
    +   undefined, we haven't run the autoconf check so provide the
    +   declaration without arguments.  If it is 0, we checked and failed
    +   to find the declaration so provide a fully prototyped one.  If it
    +   is 1, we found it so don't provide any declaration at all.  */
    +#if !HAVE_DECL_GETOPT
    +#if defined (__GNU_LIBRARY__) || defined (HAVE_DECL_GETOPT)
    +/* Many other libraries have conflicting prototypes for getopt, with
    +   differences in the consts, in unistd.h.  To avoid compilation
    +   errors, only prototype getopt for the GNU C library.  */
    +extern int getopt (int argc, char *const *argv, const char *shortopts);
    +#else
    +#ifndef __cplusplus
    +extern int getopt ();
    +#endif /* __cplusplus */
    +#endif
    +#endif /* !HAVE_DECL_GETOPT */
    +
    +extern int getopt_long (int argc, char *const *argv, const char *shortopts,
    +		        const struct option *longopts, int *longind);
    +extern int getopt_long_only (int argc, char *const *argv,
    +			     const char *shortopts,
    +		             const struct option *longopts, int *longind);
    +
    +/* Internal only.  Users should not call this directly.  */
    +extern int _getopt_internal (int argc, char *const *argv,
    +			     const char *shortopts,
    +		             const struct option *longopts, int *longind,
    +			     int long_only);
    +#else /* not __STDC__ */
    +extern int getopt ();
    +extern int getopt_long ();
    +extern int getopt_long_only ();
    +
    +extern int _getopt_internal ();
    +#endif /* __STDC__ */
    +
    +#ifdef	__cplusplus
    +}
    +#endif
    +
    +#endif /* getopt.h */
    
  • GPL/DemanglerGnu/src/demangler_gnu/headers/libiberty.h+690 0 added
    @@ -0,0 +1,690 @@
    +/* ###
    + * IP: GPL 3
    + * REVIEWED: YES
    + */
    +/* Function declarations for libiberty.
    +
    +   Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
    +   2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
    +   
    +   Note - certain prototypes declared in this header file are for
    +   functions whoes implementation copyright does not belong to the
    +   FSF.  Those prototypes are present in this file for reference
    +   purposes only and their presence in this file should not construed
    +   as an indication of ownership by the FSF of the implementation of
    +   those functions in any way or form whatsoever.
    +
    +   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, 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., 51 Franklin Street - Fifth Floor,
    +   Boston, MA 02110-1301, USA.
    +   
    +   Written by Cygnus Support, 1994.
    +
    +   The libiberty library provides a number of functions which are
    +   missing on some operating systems.  We do not declare those here,
    +   to avoid conflicts with the system header files on operating
    +   systems that do support those functions.  In this file we only
    +   declare those functions which are specific to libiberty.  */
    +
    +#ifndef LIBIBERTY_H
    +#define LIBIBERTY_H
    +
    +#ifdef __cplusplus
    +extern "C" {
    +#endif
    +
    +#include "ansidecl.h"
    +
    +/* Get a definition for size_t.  */
    +#include <stddef.h>
    +/* Get a definition for va_list.  */
    +#include <stdarg.h>
    +
    +#include <stdio.h>
    +
    +/* If the OS supports it, ensure that the supplied stream is setup to
    +   avoid any multi-threaded locking.  Otherwise leave the FILE pointer
    +   unchanged.  If the stream is NULL do nothing.  */
    +
    +extern void unlock_stream (FILE *);
    +
    +/* If the OS supports it, ensure that the standard I/O streams, stdin,
    +   stdout and stderr are setup to avoid any multi-threaded locking.
    +   Otherwise do nothing.  */
    +
    +extern void unlock_std_streams (void);
    +
    +/* Open and return a FILE pointer.  If the OS supports it, ensure that
    +   the stream is setup to avoid any multi-threaded locking.  Otherwise
    +   return the FILE pointer unchanged.  */
    +
    +extern FILE *fopen_unlocked (const char *, const char *);
    +extern FILE *fdopen_unlocked (int, const char *);
    +extern FILE *freopen_unlocked (const char *, const char *, FILE *);
    +
    +/* Build an argument vector from a string.  Allocates memory using
    +   malloc.  Use freeargv to free the vector.  */
    +
    +extern char **buildargv (const char *) ATTRIBUTE_MALLOC;
    +
    +/* Free a vector returned by buildargv.  */
    +
    +extern void freeargv (char **);
    +
    +/* Duplicate an argument vector. Allocates memory using malloc.  Use
    +   freeargv to free the vector.  */
    +
    +extern char **dupargv (char **) ATTRIBUTE_MALLOC;
    +
    +/* Expand "@file" arguments in argv.  */
    +
    +extern void expandargv PARAMS ((int *, char ***));
    +
    +/* Write argv to an @-file, inserting necessary quoting.  */
    +
    +extern int writeargv PARAMS ((char **, FILE *));
    +
    +/* Return the number of elements in argv.  */
    +
    +extern int countargv (char**);
    +
    +/* Return the last component of a path name.  Note that we can't use a
    +   prototype here because the parameter is declared inconsistently
    +   across different systems, sometimes as "char *" and sometimes as
    +   "const char *" */
    +
    +/* HAVE_DECL_* is a three-state macro: undefined, 0 or 1.  If it is
    +   undefined, we haven't run the autoconf check so provide the
    +   declaration without arguments.  If it is 0, we checked and failed
    +   to find the declaration so provide a fully prototyped one.  If it
    +   is 1, we found it so don't provide any declaration at all.  */
    +#if !HAVE_DECL_BASENAME
    +#if defined (__GNU_LIBRARY__ ) || defined (__linux__) || defined (__FreeBSD__) || defined (__OpenBSD__) || defined(__NetBSD__) || defined (__CYGWIN__) || defined (__CYGWIN32__) || defined (__MINGW32__) || defined (HAVE_DECL_BASENAME)
    +extern char *basename (const char *);
    +#else
    +/* Do not allow basename to be used if there is no prototype seen.  We
    +   either need to use the above prototype or have one from
    +   autoconf which would result in HAVE_DECL_BASENAME being set.  */
    +#define basename basename_cannot_be_used_without_a_prototype
    +#endif
    +#endif
    +
    +/* A well-defined basename () that is always compiled in.  */
    +
    +extern const char *lbasename (const char *);
    +
    +/* Same, but assumes DOS semantics (drive name, backslash is also a
    +   dir separator) regardless of host.  */
    +
    +extern const char *dos_lbasename (const char *);
    +
    +/* Same, but assumes Unix semantics (absolute paths always start with
    +   a slash, only forward slash is accepted as dir separator)
    +   regardless of host.  */
    +
    +extern const char *unix_lbasename (const char *);
    +
    +/* A well-defined realpath () that is always compiled in.  */
    +
    +extern char *lrealpath (const char *);
    +
    +/* Concatenate an arbitrary number of strings.  You must pass NULL as
    +   the last argument of this function, to terminate the list of
    +   strings.  Allocates memory using xmalloc.  */
    +
    +extern char *concat (const char *, ...) ATTRIBUTE_MALLOC ATTRIBUTE_SENTINEL;
    +
    +/* Concatenate an arbitrary number of strings.  You must pass NULL as
    +   the last argument of this function, to terminate the list of
    +   strings.  Allocates memory using xmalloc.  The first argument is
    +   not one of the strings to be concatenated, but if not NULL is a
    +   pointer to be freed after the new string is created, similar to the
    +   way xrealloc works.  */
    +
    +extern char *reconcat (char *, const char *, ...) ATTRIBUTE_MALLOC ATTRIBUTE_SENTINEL;
    +
    +/* Determine the length of concatenating an arbitrary number of
    +   strings.  You must pass NULL as the last argument of this function,
    +   to terminate the list of strings.  */
    +
    +extern unsigned long concat_length (const char *, ...) ATTRIBUTE_SENTINEL;
    +
    +/* Concatenate an arbitrary number of strings into a SUPPLIED area of
    +   memory.  You must pass NULL as the last argument of this function,
    +   to terminate the list of strings.  The supplied memory is assumed
    +   to be large enough.  */
    +
    +extern char *concat_copy (char *, const char *, ...) ATTRIBUTE_SENTINEL;
    +
    +/* Concatenate an arbitrary number of strings into a GLOBAL area of
    +   memory.  You must pass NULL as the last argument of this function,
    +   to terminate the list of strings.  The supplied memory is assumed
    +   to be large enough.  */
    +
    +extern char *concat_copy2 (const char *, ...) ATTRIBUTE_SENTINEL;
    +
    +/* This is the global area used by concat_copy2.  */
    +
    +extern char *libiberty_concat_ptr;
    +
    +/* Concatenate an arbitrary number of strings.  You must pass NULL as
    +   the last argument of this function, to terminate the list of
    +   strings.  Allocates memory using alloca.  The arguments are
    +   evaluated twice!  */
    +#define ACONCAT(ACONCAT_PARAMS) \
    +  (libiberty_concat_ptr = (char *) alloca (concat_length ACONCAT_PARAMS + 1), \
    +   concat_copy2 ACONCAT_PARAMS)
    +
    +/* Check whether two file descriptors refer to the same file.  */
    +
    +extern int fdmatch (int fd1, int fd2);
    +
    +/* Return the position of the first bit set in the argument.  */
    +/* Prototypes vary from system to system, so we only provide a
    +   prototype on systems where we know that we need it.  */
    +#if defined (HAVE_DECL_FFS) && !HAVE_DECL_FFS
    +extern int ffs(int);
    +#endif
    +
    +/* Get the working directory.  The result is cached, so don't call
    +   chdir() between calls to getpwd().  */
    +
    +extern char * getpwd (void);
    +
    +/* Get the current time.  */
    +/* Prototypes vary from system to system, so we only provide a
    +   prototype on systems where we know that we need it.  */
    +#ifdef __MINGW32__
    +/* Forward declaration to avoid #include <sys/time.h>.   */
    +struct timeval;
    +extern int gettimeofday (struct timeval *, void *); 
    +#endif
    +
    +/* Get the amount of time the process has run, in microseconds.  */
    +
    +extern long get_run_time (void);
    +
    +/* Generate a relocated path to some installation directory.  Allocates
    +   return value using malloc.  */
    +
    +extern char *make_relative_prefix (const char *, const char *,
    +                                   const char *) ATTRIBUTE_MALLOC;
    +
    +/* Generate a relocated path to some installation directory without
    +   attempting to follow any soft links.  Allocates
    +   return value using malloc.  */
    +
    +extern char *make_relative_prefix_ignore_links (const char *, const char *,
    +						const char *) ATTRIBUTE_MALLOC;
    +
    +/* Choose a temporary directory to use for scratch files.  */
    +
    +extern char *choose_temp_base (void) ATTRIBUTE_MALLOC;
    +
    +/* Return a temporary file name or NULL if unable to create one.  */
    +
    +extern char *make_temp_file (const char *) ATTRIBUTE_MALLOC;
    +
    +/* Remove a link to a file unless it is special. */
    +
    +extern int unlink_if_ordinary (const char *);
    +
    +/* Allocate memory filled with spaces.  Allocates using malloc.  */
    +
    +extern const char *spaces (int count);
    +
    +/* Return the maximum error number for which strerror will return a
    +   string.  */
    +
    +extern int errno_max (void);
    +
    +/* Return the name of an errno value (e.g., strerrno (EINVAL) returns
    +   "EINVAL").  */
    +
    +extern const char *strerrno (int);
    +
    +/* Given the name of an errno value, return the value.  */
    +
    +extern int strtoerrno (const char *);
    +
    +/* ANSI's strerror(), but more robust.  */
    +
    +extern char *xstrerror (int);
    +
    +/* Return the maximum signal number for which strsignal will return a
    +   string.  */
    +
    +extern int signo_max (void);
    +
    +/* Return a signal message string for a signal number
    +   (e.g., strsignal (SIGHUP) returns something like "Hangup").  */
    +/* This is commented out as it can conflict with one in system headers.
    +   We still document its existence though.  */
    +
    +/*extern const char *strsignal (int);*/
    +
    +/* Return the name of a signal number (e.g., strsigno (SIGHUP) returns
    +   "SIGHUP").  */
    +
    +extern const char *strsigno (int);
    +
    +/* Given the name of a signal, return its number.  */
    +
    +extern int strtosigno (const char *);
    +
    +/* Register a function to be run by xexit.  Returns 0 on success.  */
    +
    +extern int xatexit (void (*fn) (void));
    +
    +/* Exit, calling all the functions registered with xatexit.  */
    +
    +extern void xexit (int status) ATTRIBUTE_NORETURN;
    +
    +/* Set the program name used by xmalloc.  */
    +
    +extern void xmalloc_set_program_name (const char *);
    +
    +/* Report an allocation failure.  */
    +extern void xmalloc_failed (size_t) ATTRIBUTE_NORETURN;
    +
    +/* Allocate memory without fail.  If malloc fails, this will print a
    +   message to stderr (using the name set by xmalloc_set_program_name,
    +   if any) and then call xexit.  */
    +
    +extern void *xmalloc (size_t) ATTRIBUTE_MALLOC;
    +
    +/* Reallocate memory without fail.  This works like xmalloc.  Note,
    +   realloc type functions are not suitable for attribute malloc since
    +   they may return the same address across multiple calls. */
    +
    +extern void *xrealloc (void *, size_t);
    +
    +/* Allocate memory without fail and set it to zero.  This works like
    +   xmalloc.  */
    +
    +extern void *xcalloc (size_t, size_t) ATTRIBUTE_MALLOC;
    +
    +/* Copy a string into a memory buffer without fail.  */
    +
    +extern char *xstrdup (const char *) ATTRIBUTE_MALLOC;
    +
    +/* Copy at most N characters from string into a buffer without fail.  */
    +
    +extern char *xstrndup (const char *, size_t) ATTRIBUTE_MALLOC;
    +
    +/* Copy an existing memory buffer to a new memory buffer without fail.  */
    +
    +extern void *xmemdup (const void *, size_t, size_t) ATTRIBUTE_MALLOC;
    +
    +/* Physical memory routines.  Return values are in BYTES.  */
    +extern double physmem_total (void);
    +extern double physmem_available (void);
    +
    +/* Compute the 32-bit CRC of a block of memory.  */
    +extern unsigned int xcrc32 (const unsigned char *, int, unsigned int);
    +
    +/* These macros provide a K&R/C89/C++-friendly way of allocating structures
    +   with nice encapsulation.  The XDELETE*() macros are technically
    +   superfluous, but provided here for symmetry.  Using them consistently
    +   makes it easier to update client code to use different allocators such
    +   as new/delete and new[]/delete[].  */
    +
    +/* Scalar allocators.  */
    +
    +#define XALLOCA(T)		((T *) alloca (sizeof (T)))
    +#define XNEW(T)			((T *) xmalloc (sizeof (T)))
    +#define XCNEW(T)		((T *) xcalloc (1, sizeof (T)))
    +#define XDUP(T, P)		((T *) xmemdup ((P), sizeof (T), sizeof (T)))
    +#define XDELETE(P)		free ((void*) (P))
    +
    +/* Array allocators.  */
    +
    +#define XALLOCAVEC(T, N)	((T *) alloca (sizeof (T) * (N)))
    +#define XNEWVEC(T, N)		((T *) xmalloc (sizeof (T) * (N)))
    +#define XCNEWVEC(T, N)		((T *) xcalloc ((N), sizeof (T)))
    +#define XDUPVEC(T, P, N)	((T *) xmemdup ((P), sizeof (T) * (N), sizeof (T) * (N)))
    +#define XRESIZEVEC(T, P, N)	((T *) xrealloc ((void *) (P), sizeof (T) * (N)))
    +#define XDELETEVEC(P)		free ((void*) (P))
    +
    +/* Allocators for variable-sized structures and raw buffers.  */
    +
    +#define XALLOCAVAR(T, S)	((T *) alloca ((S)))
    +#define XNEWVAR(T, S)		((T *) xmalloc ((S)))
    +#define XCNEWVAR(T, S)		((T *) xcalloc (1, (S)))
    +#define XDUPVAR(T, P, S1, S2)	((T *) xmemdup ((P), (S1), (S2)))
    +#define XRESIZEVAR(T, P, S)	((T *) xrealloc ((P), (S)))
    +
    +/* Type-safe obstack allocator.  */
    +
    +#define XOBNEW(O, T)		((T *) obstack_alloc ((O), sizeof (T)))
    +#define XOBNEWVEC(O, T, N)	((T *) obstack_alloc ((O), sizeof (T) * (N)))
    +#define XOBNEWVAR(O, T, S)	((T *) obstack_alloc ((O), (S)))
    +#define XOBFINISH(O, T)         ((T) obstack_finish ((O)))
    +
    +/* hex character manipulation routines */
    +
    +#define _hex_array_size 256
    +#define _hex_bad	99
    +extern const unsigned char _hex_value[_hex_array_size];
    +extern void hex_init (void);
    +#define hex_p(c)	(hex_value (c) != _hex_bad)
    +/* If you change this, note well: Some code relies on side effects in
    +   the argument being performed exactly once.  */
    +#define hex_value(c)	((unsigned int) _hex_value[(unsigned char) (c)])
    +
    +/* Flags for pex_init.  These are bits to be or'ed together.  */
    +
    +/* Record subprocess times, if possible.  */
    +#define PEX_RECORD_TIMES	0x1
    +
    +/* Use pipes for communication between processes, if possible.  */
    +#define PEX_USE_PIPES		0x2
    +
    +/* Save files used for communication between processes.  */
    +#define PEX_SAVE_TEMPS		0x4
    +
    +/* Prepare to execute one or more programs, with standard output of
    +   each program fed to standard input of the next.
    +   FLAGS	As above.
    +   PNAME	The name of the program to report in error messages.
    +   TEMPBASE	A base name to use for temporary files; may be NULL to
    +   		use a random name.
    +   Returns NULL on error.  */
    +
    +extern struct pex_obj *pex_init (int flags, const char *pname,
    +				 const char *tempbase);
    +
    +/* Flags for pex_run.  These are bits to be or'ed together.  */
    +
    +/* Last program in pipeline.  Standard output of program goes to
    +   OUTNAME, or, if OUTNAME is NULL, to standard output of caller.  Do
    +   not set this if you want to call pex_read_output.  After this is
    +   set, pex_run may no longer be called with the same struct
    +   pex_obj.  */
    +#define PEX_LAST		0x1
    +
    +/* Search for program in executable search path.  */
    +#define PEX_SEARCH		0x2
    +
    +/* OUTNAME is a suffix.  */
    +#define PEX_SUFFIX		0x4
    +
    +/* Send program's standard error to standard output.  */
    +#define PEX_STDERR_TO_STDOUT	0x8
    +
    +/* Input file should be opened in binary mode.  This flag is ignored
    +   on Unix.  */
    +#define PEX_BINARY_INPUT	0x10
    +
    +/* Output file should be opened in binary mode.  This flag is ignored
    +   on Unix.  For proper behaviour PEX_BINARY_INPUT and
    +   PEX_BINARY_OUTPUT have to match appropriately--i.e., a call using
    +   PEX_BINARY_OUTPUT should be followed by a call using
    +   PEX_BINARY_INPUT.  */
    +#define PEX_BINARY_OUTPUT	0x20
    +
    +/* Capture stderr to a pipe.  The output can be read by
    +   calling pex_read_err and reading from the returned
    +   FILE object.  This flag may be specified only for
    +   the last program in a pipeline.  
    +
    +   This flag is supported only on Unix and Windows.  */
    +#define PEX_STDERR_TO_PIPE	0x40
    +
    +/* Capture stderr in binary mode.  This flag is ignored
    +   on Unix.  */
    +#define PEX_BINARY_ERROR	0x80
    +
    +
    +/* Execute one program.  Returns NULL on success.  On error returns an
    +   error string (typically just the name of a system call); the error
    +   string is statically allocated.
    +
    +   OBJ		Returned by pex_init.
    +
    +   FLAGS	As above.
    +
    +   EXECUTABLE	The program to execute.
    +
    +   ARGV		NULL terminated array of arguments to pass to the program.
    +
    +   OUTNAME	Sets the output file name as follows:
    +
    +		PEX_SUFFIX set (OUTNAME may not be NULL):
    +		  TEMPBASE parameter to pex_init not NULL:
    +		    Output file name is the concatenation of TEMPBASE
    +		    and OUTNAME.
    +		  TEMPBASE is NULL:
    +		    Output file name is a random file name ending in
    +		    OUTNAME.
    +		PEX_SUFFIX not set:
    +		  OUTNAME not NULL:
    +		    Output file name is OUTNAME.
    +		  OUTNAME NULL, TEMPBASE not NULL:
    +		    Output file name is randomly chosen using
    +		    TEMPBASE.
    +		  OUTNAME NULL, TEMPBASE NULL:
    +		    Output file name is randomly chosen.
    +
    +		If PEX_LAST is not set, the output file name is the
    +   		name to use for a temporary file holding stdout, if
    +   		any (there will not be a file if PEX_USE_PIPES is set
    +   		and the system supports pipes).  If a file is used, it
    +   		will be removed when no longer needed unless
    +   		PEX_SAVE_TEMPS is set.
    +
    +		If PEX_LAST is set, and OUTNAME is not NULL, standard
    +   		output is written to the output file name.  The file
    +   		will not be removed.  If PEX_LAST and PEX_SUFFIX are
    +   		both set, TEMPBASE may not be NULL.
    +
    +   ERRNAME	If not NULL, this is the name of a file to which
    +		standard error is written.  If NULL, standard error of
    +		the program is standard error of the caller.
    +
    +   ERR		On an error return, *ERR is set to an errno value, or
    +   		to 0 if there is no relevant errno.
    +*/
    +
    +extern const char *pex_run (struct pex_obj *obj, int flags,
    +			    const char *executable, char * const *argv,
    +			    const char *outname, const char *errname,
    +			    int *err);
    +
    +/* As for pex_run (), but takes an extra parameter to enable the
    +   environment for the child process to be specified.
    +
    +   ENV		The environment for the child process, specified as
    +		an array of character pointers.  Each element of the
    +		array should point to a string of the form VAR=VALUE,
    +                with the exception of the last element which must be
    +                a null pointer.
    +*/
    +
    +extern const char *pex_run_in_environment (struct pex_obj *obj, int flags,
    +			                   const char *executable,
    +                                           char * const *argv,
    +                                           char * const *env,
    +              	          		   const char *outname,
    +					   const char *errname, int *err);
    +
    +/* Return a stream for a temporary file to pass to the first program
    +   in the pipeline as input.  The file name is chosen as for pex_run.
    +   pex_run closes the file automatically; don't close it yourself.  */
    +
    +extern FILE *pex_input_file (struct pex_obj *obj, int flags,
    +                             const char *in_name);
    +
    +/* Return a stream for a pipe connected to the standard input of the
    +   first program in the pipeline.  You must have passed
    +   `PEX_USE_PIPES' to `pex_init'.  Close the returned stream
    +   yourself.  */
    +
    +extern FILE *pex_input_pipe (struct pex_obj *obj, int binary);
    +
    +/* Read the standard output of the last program to be executed.
    +   pex_run can not be called after this.  BINARY should be non-zero if
    +   the file should be opened in binary mode; this is ignored on Unix.
    +   Returns NULL on error.  Don't call fclose on the returned FILE; it
    +   will be closed by pex_free.  */
    +
    +extern FILE *pex_read_output (struct pex_obj *, int binary);
    +
    +/* Read the standard error of the last program to be executed.
    +   pex_run can not be called after this.  BINARY should be non-zero if
    +   the file should be opened in binary mode; this is ignored on Unix.
    +   Returns NULL on error.  Don't call fclose on the returned FILE; it
    +   will be closed by pex_free.  */
    +
    +extern FILE *pex_read_err (struct pex_obj *, int binary);
    +
    +/* Return exit status of all programs in VECTOR.  COUNT indicates the
    +   size of VECTOR.  The status codes in the vector are in the order of
    +   the calls to pex_run.  Returns 0 on error, 1 on success.  */
    +
    +extern int pex_get_status (struct pex_obj *, int count, int *vector);
    +
    +/* Return times of all programs in VECTOR.  COUNT indicates the size
    +   of VECTOR.  struct pex_time is really just struct timeval, but that
    +   is not portable to all systems.  Returns 0 on error, 1 on
    +   success.  */
    +
    +struct pex_time
    +{
    +  unsigned long user_seconds;
    +  unsigned long user_microseconds;
    +  unsigned long system_seconds;
    +  unsigned long system_microseconds;
    +};
    +
    +extern int pex_get_times (struct pex_obj *, int count,
    +			  struct pex_time *vector);
    +
    +/* Clean up a pex_obj.  If you have not called pex_get_times or
    +   pex_get_status, this will try to kill the subprocesses.  */
    +
    +extern void pex_free (struct pex_obj *);
    +
    +/* Just execute one program.  Return value is as for pex_run.
    +   FLAGS	Combination of PEX_SEARCH and PEX_STDERR_TO_STDOUT.
    +   EXECUTABLE	As for pex_run.
    +   ARGV		As for pex_run.
    +   PNAME	As for pex_init.
    +   OUTNAME	As for pex_run when PEX_LAST is set.
    +   ERRNAME	As for pex_run.
    +   STATUS	Set to exit status on success.
    +   ERR		As for pex_run.
    +*/
    +
    +extern const char *pex_one (int flags, const char *executable,
    +			    char * const *argv, const char *pname,
    +			    const char *outname, const char *errname,
    +			    int *status, int *err);
    +
    +/* pexecute and pwait are the old pexecute interface, still here for
    +   backward compatibility.  Don't use these for new code.  Instead,
    +   use pex_init/pex_run/pex_get_status/pex_free, or pex_one.  */
    +
    +/* Definitions used by the pexecute routine.  */
    +
    +#define PEXECUTE_FIRST   1
    +#define PEXECUTE_LAST    2
    +#define PEXECUTE_ONE     (PEXECUTE_FIRST + PEXECUTE_LAST)
    +#define PEXECUTE_SEARCH  4
    +#define PEXECUTE_VERBOSE 8
    +
    +/* Execute a program.  */
    +
    +extern int pexecute (const char *, char * const *, const char *,
    +                     const char *, char **, char **, int);
    +
    +/* Wait for pexecute to finish.  */
    +
    +extern int pwait (int, int *, int);
    +
    +#if !HAVE_DECL_ASPRINTF
    +/* Like sprintf but provides a pointer to malloc'd storage, which must
    +   be freed by the caller.  */
    +
    +extern int asprintf (char **, const char *, ...) ATTRIBUTE_PRINTF_2;
    +#endif
    +
    +#if !HAVE_DECL_VASPRINTF
    +/* Like vsprintf but provides a pointer to malloc'd storage, which
    +   must be freed by the caller.  */
    +
    +extern int vasprintf (char **, const char *, va_list) ATTRIBUTE_PRINTF(2,0);
    +#endif
    +
    +#if defined(HAVE_DECL_SNPRINTF) && !HAVE_DECL_SNPRINTF
    +/* Like sprintf but prints at most N characters.  */
    +extern int snprintf (char *, size_t, const char *, ...) ATTRIBUTE_PRINTF_3;
    +#endif
    +
    +#if defined(HAVE_DECL_VSNPRINTF) && !HAVE_DECL_VSNPRINTF
    +/* Like vsprintf but prints at most N characters.  */
    +extern int vsnprintf (char *, size_t, const char *, va_list) ATTRIBUTE_PRINTF(3,0);
    +#endif
    +
    +#if defined(HAVE_DECL_STRVERSCMP) && !HAVE_DECL_STRVERSCMP
    +/* Compare version strings.  */
    +extern int strverscmp (const char *, const char *);
    +#endif
    +
    +/* Set the title of a process */
    +extern void setproctitle (const char *name, ...);
    +
    +/* Increase stack limit if possible.  */
    +extern void stack_limit_increase (unsigned long);
    +
    +#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
    +
    +/* Drastically simplified alloca configurator.  If we're using GCC,
    +   we use __builtin_alloca; otherwise we use the C alloca.  The C
    +   alloca is always available.  You can override GCC by defining
    +   USE_C_ALLOCA yourself.  The canonical autoconf macro C_ALLOCA is
    +   also set/unset as it is often used to indicate whether code needs
    +   to call alloca(0).  */
    +extern void *C_alloca (size_t) ATTRIBUTE_MALLOC;
    +#undef alloca
    +#if GCC_VERSION >= 2000 && !defined USE_C_ALLOCA
    +# define alloca(x) __builtin_alloca(x)
    +# undef C_ALLOCA
    +# define ASTRDUP(X) \
    +  (__extension__ ({ const char *const libiberty_optr = (X); \
    +   const unsigned long libiberty_len = strlen (libiberty_optr) + 1; \
    +   char *const libiberty_nptr = (char *const) alloca (libiberty_len); \
    +   (char *) memcpy (libiberty_nptr, libiberty_optr, libiberty_len); }))
    +#else
    +# define alloca(x) C_alloca(x)
    +# undef USE_C_ALLOCA
    +# define USE_C_ALLOCA 1
    +# undef C_ALLOCA
    +# define C_ALLOCA 1
    +extern const char *libiberty_optr;
    +extern char *libiberty_nptr;
    +extern unsigned long libiberty_len;
    +# define ASTRDUP(X) \
    +  (libiberty_optr = (X), \
    +   libiberty_len = strlen (libiberty_optr) + 1, \
    +   libiberty_nptr = (char *) alloca (libiberty_len), \
    +   (char *) memcpy (libiberty_nptr, libiberty_optr, libiberty_len))
    +#endif
    +
    +#ifdef __cplusplus
    +}
    +#endif
    +
    +
    +#endif /* ! defined (LIBIBERTY_H) */
    
  • GPL/DemanglerGnu/src/demangler_gnu/headers/safe-ctype.h+154 0 added
    @@ -0,0 +1,154 @@
    +/* ###
    + * IP: LGPL 3.0
    + * REVIEWED: YES
    + */
    +/* <ctype.h> replacement macros.
    +
    +   Copyright (C) 2000, 2001 Free Software Foundation, Inc.
    +   Contributed by Zack Weinberg <zackw@stanford.edu>.
    +
    +This file is part of the libiberty library.
    +Libiberty is free software; you can redistribute it and/or
    +modify it under the terms of the GNU Library General Public
    +License as published by the Free Software Foundation; either
    +version 2 of the License, or (at your option) any later version.
    +
    +Libiberty 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
    +Library General Public License for more details.
    +
    +You should have received a copy of the GNU Library General Public
    +License along with libiberty; see the file COPYING.LIB.  If
    +not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
    +Boston, MA 02110-1301, USA.  */
    +
    +/* This is a compatible replacement of the standard C library's <ctype.h>
    +   with the following properties:
    +
    +   - Implements all isxxx() macros required by C99.
    +   - Also implements some character classes useful when
    +     parsing C-like languages.
    +   - Does not change behavior depending on the current locale.
    +   - Behaves properly for all values in the range of a signed or
    +     unsigned char.
    +
    +   To avoid conflicts, this header defines the isxxx functions in upper
    +   case, e.g. ISALPHA not isalpha.  */
    +
    +#ifndef SAFE_CTYPE_H
    +#define SAFE_CTYPE_H
    +
    +/* Determine host character set.  */
    +#define HOST_CHARSET_UNKNOWN 0
    +#define HOST_CHARSET_ASCII   1
    +#define HOST_CHARSET_EBCDIC  2
    +
    +#if  '\n' == 0x0A && ' ' == 0x20 && '0' == 0x30 \
    +   && 'A' == 0x41 && 'a' == 0x61 && '!' == 0x21
    +#  define HOST_CHARSET HOST_CHARSET_ASCII
    +#else
    +# if '\n' == 0x15 && ' ' == 0x40 && '0' == 0xF0 \
    +   && 'A' == 0xC1 && 'a' == 0x81 && '!' == 0x5A
    +#  define HOST_CHARSET HOST_CHARSET_EBCDIC
    +# else
    +#  define HOST_CHARSET HOST_CHARSET_UNKNOWN
    +# endif
    +#endif
    +
    +/* Categories.  */
    +
    +enum {
    +  /* In C99 */
    +  _sch_isblank  = 0x0001,	/* space \t */
    +  _sch_iscntrl  = 0x0002,	/* nonprinting characters */
    +  _sch_isdigit  = 0x0004,	/* 0-9 */
    +  _sch_islower  = 0x0008,	/* a-z */
    +  _sch_isprint  = 0x0010,	/* any printing character including ' ' */
    +  _sch_ispunct  = 0x0020,	/* all punctuation */
    +  _sch_isspace  = 0x0040,	/* space \t \n \r \f \v */
    +  _sch_isupper  = 0x0080,	/* A-Z */
    +  _sch_isxdigit = 0x0100,	/* 0-9A-Fa-f */
    +
    +  /* Extra categories useful to cpplib.  */
    +  _sch_isidst	= 0x0200,	/* A-Za-z_ */
    +  _sch_isvsp    = 0x0400,	/* \n \r */
    +  _sch_isnvsp   = 0x0800,	/* space \t \f \v \0 */
    +
    +  /* Combinations of the above.  */
    +  _sch_isalpha  = _sch_isupper|_sch_islower,	/* A-Za-z */
    +  _sch_isalnum  = _sch_isalpha|_sch_isdigit,	/* A-Za-z0-9 */
    +  _sch_isidnum  = _sch_isidst|_sch_isdigit,	/* A-Za-z0-9_ */
    +  _sch_isgraph  = _sch_isalnum|_sch_ispunct,	/* isprint and not space */
    +  _sch_iscppsp  = _sch_isvsp|_sch_isnvsp,	/* isspace + \0 */
    +  _sch_isbasic  = _sch_isprint|_sch_iscppsp     /* basic charset of ISO C
    +						   (plus ` and @)  */
    +};
    +
    +/* Character classification.  */
    +extern const unsigned short _sch_istable[256];
    +
    +#define _sch_test(c, bit) (_sch_istable[(c) & 0xff] & (unsigned short)(bit))
    +
    +#define ISALPHA(c)  _sch_test(c, _sch_isalpha)
    +#define ISALNUM(c)  _sch_test(c, _sch_isalnum)
    +#define ISBLANK(c)  _sch_test(c, _sch_isblank)
    +#define ISCNTRL(c)  _sch_test(c, _sch_iscntrl)
    +#define ISDIGIT(c)  _sch_test(c, _sch_isdigit)
    +#define ISGRAPH(c)  _sch_test(c, _sch_isgraph)
    +#define ISLOWER(c)  _sch_test(c, _sch_islower)
    +#define ISPRINT(c)  _sch_test(c, _sch_isprint)
    +#define ISPUNCT(c)  _sch_test(c, _sch_ispunct)
    +#define ISSPACE(c)  _sch_test(c, _sch_isspace)
    +#define ISUPPER(c)  _sch_test(c, _sch_isupper)
    +#define ISXDIGIT(c) _sch_test(c, _sch_isxdigit)
    +
    +#define ISIDNUM(c)	_sch_test(c, _sch_isidnum)
    +#define ISIDST(c)	_sch_test(c, _sch_isidst)
    +#define IS_ISOBASIC(c)	_sch_test(c, _sch_isbasic)
    +#define IS_VSPACE(c)	_sch_test(c, _sch_isvsp)
    +#define IS_NVSPACE(c)	_sch_test(c, _sch_isnvsp)
    +#define IS_SPACE_OR_NUL(c)	_sch_test(c, _sch_iscppsp)
    +
    +/* Character transformation.  */
    +extern const unsigned char  _sch_toupper[256];
    +extern const unsigned char  _sch_tolower[256];
    +#define TOUPPER(c) _sch_toupper[(c) & 0xff]
    +#define TOLOWER(c) _sch_tolower[(c) & 0xff]
    +
    +/* Prevent the users of safe-ctype.h from accidently using the routines
    +   from ctype.h.  Initially, the approach was to produce an error when
    +   detecting that ctype.h has been included.  But this was causing
    +   trouble as ctype.h might get indirectly included as a result of
    +   including another system header (for instance gnulib's stdint.h).
    +   So we include ctype.h here and then immediately redefine its macros.  */
    +
    +#include <ctype.h>
    +#undef isalpha
    +#define isalpha(c) do_not_use_isalpha_with_safe_ctype
    +#undef isalnum
    +#define isalnum(c) do_not_use_isalnum_with_safe_ctype
    +#undef iscntrl
    +#define iscntrl(c) do_not_use_iscntrl_with_safe_ctype
    +#undef isdigit
    +#define isdigit(c) do_not_use_isdigit_with_safe_ctype
    +#undef isgraph
    +#define isgraph(c) do_not_use_isgraph_with_safe_ctype
    +#undef islower
    +#define islower(c) do_not_use_islower_with_safe_ctype
    +#undef isprint
    +#define isprint(c) do_not_use_isprint_with_safe_ctype
    +#undef ispunct
    +#define ispunct(c) do_not_use_ispunct_with_safe_ctype
    +#undef isspace
    +#define isspace(c) do_not_use_isspace_with_safe_ctype
    +#undef isupper
    +#define isupper(c) do_not_use_isupper_with_safe_ctype
    +#undef isxdigit
    +#define isxdigit(c) do_not_use_isxdigit_with_safe_ctype
    +#undef toupper
    +#define toupper(c) do_not_use_toupper_with_safe_ctype
    +#undef tolower
    +#define tolower(c) do_not_use_tolower_with_safe_ctype
    +
    +#endif /* SAFE_CTYPE_H */
    
  • GPL/DemanglerGnu/src/demangler_gnu/README.txt+94 0 added
    @@ -0,0 +1,94 @@
    +PURPOSE
    +
    +This is a readme file to note the changes made to the binutils-2.24 source 
    +code in order for Ghidra to build its GNU demangler.
    +
    +
    +
    +
    +COPIED SOURCE CODE / BUILDING RESTRICTIONS
    +
    +Most of the files used to build the Ghidra GNU demangler are copied from binutils and have
    +not been changed.  Further, the files in this directory are a small subset of the files used to
    +build the binutils suite.  By copying specific files we are able to use Make and Visual Studio
    +to build a stand alone demangler without having to perform the more complicated build needed
    +to build binutils.  Specifically, we do not have to run the configure utility that is 
    +provided by binutils.   This is critical, as we are using Visual Studio to build on Windows, 
    +which does not have the configure utility support.   If we ever wished to build the entire 
    +binutils suite on Windows, then we would most likely need to use a GNU environment made for
    +Windows, such as MinGW.
    +
    +
    +
    +
    +CHANGES TO BINUTILS SOURCE
    +
    +cplus-dem.c
    +
    +To this file was added about 400 lines of source code.  Previously, this file contained a 
    +main method that we used to build our stand alone demangler.   The current version of 
    +binutils does not have this main method.  Instead, binutils has only a main method in 
    +cp-demangle.c for building the stand alone demangler.  The c++filt utility is created using 
    +a main method inside of cxxfilt.c.  We could not build that utility without using the 
    +more complicated build system mentioned above.  
    +
    +In order to gain full functionality contained in the c++filt utility, we copied the main 
    +method from cxxfilt.c and placed it, along with supporting methods, into cplus-dem.c.  This 
    +allows us to perform a simple build of the stand alone demangler, with less source files 
    +required.
    +
    +cp-demangle.c *
    +
    +This file contains a small, two-line change to send a newline character ('\n') along with 
    +a flush to the output stream.  Without this change, the program, when called repeatedly from 
    +Ghidra would eventually hang.  This is due to the nature of how Ghidra reads results in a 
    +line-oriented fashion.
    +
    +*This change is no longer used, as we do not use the main method inside of this file, but have
    +switched to the main method we made and placed into cplus-dem.c.
    +
    +
    +
    +
    +UPDATING
    +
    +If we ever wish to update to a newer version of binutils, then we will need to re-copy the files
    +in this directory and then rebuild the main method we created inside of cplus-dem.c.  That is, 
    +unless at least one of the following changes happens: 
    +
    +1) the stand alone demangler in cp-demangle has full c++filt support, or
    +2) binutils has put the main method back inside cplus-dem.c, or 
    +3) building a stand alone c++filt is simple enough that we can do it on each platform, or
    +4) we decide to build the entire binutils suite and use the full c++filt binary. 
    +
    +
    +
    +
    +SOURCE FILES NEEDED BY OS
    +
    +
    +*nix / Mac
    +
    +ansidecl.h
    +argv.c
    +cp-demangle.c
    +cp-demangle.h
    +cplus-dem.c
    +demangle.h
    +dyn-string.c
    +dyn-string.h
    +getopt.c
    +getopt.h
    +libiberty.h
    +safe-ctype.c
    +safe-ctype.h
    +xexit.c
    +xstrdup.c
    +
    +WINDOWS
    +
    +
    +
    +alloca.c
    +getopt1.c
    +
    
  • GPL/DMG/build.gradle+54 0 added
    @@ -0,0 +1,54 @@
    +apply plugin: 'eclipse'
    +eclipse.project.name = 'GPL DMG'
    +
    +/*********************************************************************************
    + *
    + * Define a new source set for dmg source because it is not part of Ghidra, it is 
    + * a standalone application that is executed and called from Ghidra. 
    + *  			
    + * see DmgServerProcessManager 
    + *
    + *********************************************************************************/
    +sourceSets {
    +	dmg {
    +		java {
    +			srcDir 'src/dmg/java'
    +		}
    +	}
    +}
    +
    +eclipse.classpath.plusConfigurations += [configurations.dmgCompile]
    +
    +dependencies {
    +	dmgCompile ':csframework@jar'
    +	dmgCompile ':hfsx@jar'
    +	dmgCompile ':hfsx_dmglib@jar'
    +}
    +
    +
    +/***************************************************************************************
    + *
    + * Task to create the dmg.jar file
    + *
    + ***************************************************************************************/
    +task dmgJar(type: Jar) {
    +	from sourceSets.dmg.output
    +	destinationDir = file("build/data/lib")
    +	baseName = 'dmg'
    +}
    +
    +jar {
    +	doLast {
    +		File f = file("build/libs/DMG.jar")
    +		delete "build/libs"
    +	}
    +}
    +
    +/***************************************************************************************
    + *
    + * plugin the jar task into global task for building and zipping contribs
    + *
    + ***************************************************************************************/
    +assemble.dependsOn dmgJar
    +
    +
    
  • GPL/DMG/certification.manifest+20 0 added
    @@ -0,0 +1,20 @@
    +##VERSION: 2.0
    +##MODULE IP: GPL 3
    +##MODULE IP: LGPL 2.1
    +##MODULE IP: Public Domain
    +.classpath||Public Domain||||END|
    +.project||Public Domain||||END|
    +Module.manifest||Public Domain||||END|
    +build.gradle||Public Domain||||END|
    +data/lib/catacombae_csframework.jar||LGPL 2.1||||END|
    +data/lib/catacombae_hfsx.jar||GPL 3||||END|
    +data/lib/catacombae_hfsx_dmglib.jar||GPL 3||||END|
    +data/lib/catacombae_iharder-base64.jar||GPL 3||||END|
    +data/lib/hfsexplorer-0_21-src.zip||GPL 3||||END|
    +data/os/win32/llio_amd64.dll||GPL 3||||END|
    +data/os/win32/llio_i386.dll||GPL 3||||END|
    +data/os/win32/llio_ia64.dll||GPL 3||||END|
    +data/os/win64/llio_amd64.dll||GPL 3||||END|
    +data/os/win64/llio_i386.dll||GPL 3||||END|
    +data/os/win64/llio_ia64.dll||GPL 3||||END|
    +data/server_memory.cfg||Public Domain||||END|
    
  • GPL/DMG/data/lib/catacombae_csframework.jar+0 0 added
  • GPL/DMG/data/lib/catacombae_hfsx_dmglib.jar+0 0 added
  • GPL/DMG/data/lib/catacombae_hfsx.jar+0 0 added
  • GPL/DMG/data/lib/catacombae_iharder-base64.jar+0 0 added
  • GPL/DMG/data/lib/hfsexplorer-0_21-src.zip+0 0 added
  • GPL/DMG/data/os/win32/llio_amd64.dll+0 0 added
  • GPL/DMG/data/os/win32/llio_i386.dll+0 0 added
  • GPL/DMG/data/os/win32/llio_ia64.dll+0 0 added
  • GPL/DMG/data/os/win64/llio_amd64.dll+0 0 added
  • GPL/DMG/data/os/win64/llio_i386.dll+0 0 added
  • GPL/DMG/data/os/win64/llio_ia64.dll+0 0 added
  • GPL/DMG/data/server_memory.cfg+1 0 added
    @@ -0,0 +1 @@
    +2048
    
  • GPL/DMG/Module.manifest+2 0 added
    @@ -0,0 +1,2 @@
    +# GPL because we have linked to GPL hsfx.jar 
    +MODULE FILE LICENSE: data/lib/dmg.jar GPL 3
    
  • GPL/DMG/src/dmg/java/mobiledevices/dmg/btree/BTreeHeaderRecordAttributes.java+17 0 added
    @@ -0,0 +1,17 @@
    +/* ###
    + * IP: Public Domain
    + */
    +package mobiledevices.dmg.btree;
    +
    +/**
    + * Represents a BTHeaderRec attributes.
    + * 
    + * @see <a href="https://opensource.apple.com/source/xnu/xnu-792/bsd/hfs/hfs_format.h.auto.html">hfs/hfs_format.h</a> 
    + */
    +public final class BTreeHeaderRecordAttributes {
    +
    +	public final static int kBTBadCloseMask = 0x00000001;
    +	public final static int kBTBigKeysMask = 0x00000002;
    +	public final static int kBTVariableIndexKeysMask = 0x00000004;
    +
    +}
    
  • GPL/DMG/src/dmg/java/mobiledevices/dmg/btree/BTreeHeaderRecord.java+116 0 added
    @@ -0,0 +1,116 @@
    +/* ###
    + * IP: Public Domain
    + */
    +package mobiledevices.dmg.btree;
    +
    +import java.io.IOException;
    +
    +import mobiledevices.dmg.ghidra.GBinaryReader;
    +
    +/**
    + * Represents a BTHeaderRec structure.
    + * 
    + * @see <a href="https://opensource.apple.com/source/xnu/xnu-792/bsd/hfs/hfs_format.h.auto.html">hfs/hfs_format.h</a> 
    + */
    +public class BTreeHeaderRecord /*implements StructConverter*/ {
    +
    +	private short treeDepth;
    +	private int rootNode;
    +	private int leafRecords;
    +	private int firstLeafNode;
    +	private int lastLeafNode;
    +	private short nodeSize;
    +	private short maxKeyLength;
    +	private int totalNodes;
    +	private int freeNodes;
    +	private short reserved1;
    +	private int clumpSize;
    +	private byte btreeType;
    +	private byte keyCompareType;
    +	private int attributes;
    +	private int[] reserved;
    +
    +	BTreeHeaderRecord(GBinaryReader reader) throws IOException {
    +		this.treeDepth = reader.readNextShort();
    +		this.rootNode = reader.readNextInt();
    +		this.leafRecords = reader.readNextInt();
    +		this.firstLeafNode = reader.readNextInt();
    +		this.lastLeafNode = reader.readNextInt();
    +		this.nodeSize = reader.readNextShort();
    +		this.maxKeyLength = reader.readNextShort();
    +		this.totalNodes = reader.readNextInt();
    +		this.freeNodes = reader.readNextInt();
    +		this.reserved1 = reader.readNextShort();
    +		this.clumpSize = reader.readNextInt();
    +		this.btreeType = reader.readNextByte();
    +		this.keyCompareType = reader.readNextByte();
    +		this.attributes = reader.readNextInt();
    +		this.reserved = reader.readNextIntArray(16);
    +	}
    +
    +	public short getTreeDepth() {
    +		return treeDepth;
    +	}
    +
    +	public int getRootNode() {
    +		return rootNode;
    +	}
    +
    +	public int getLeafRecords() {
    +		return leafRecords;
    +	}
    +
    +	public int getFirstLeafNode() {
    +		return firstLeafNode;
    +	}
    +
    +	public int getLastLeafNode() {
    +		return lastLeafNode;
    +	}
    +
    +	public short getNodeSize() {
    +		return nodeSize;
    +	}
    +
    +	public short getMaxKeyLength() {
    +		return maxKeyLength;
    +	}
    +
    +	public int getTotalNodes() {
    +		return totalNodes;
    +	}
    +
    +	public int getFreeNodes() {
    +		return freeNodes;
    +	}
    +
    +	public short getReserved1() {
    +		return reserved1;
    +	}
    +
    +	public int getClumpSize() {
    +		return clumpSize;
    +	}
    +
    +	public byte getBtreeType() {
    +		return btreeType;
    +	}
    +
    +	public byte getKeyCompareType() {
    +		return keyCompareType;
    +	}
    +
    +	public int getAttributes() {
    +		return attributes;
    +	}
    +
    +	public int[] getReserved() {
    +		return reserved;
    +	}
    +
    +//	@Override
    +//	public DataType toDataType() throws DuplicateNameException, IOException {
    +//		return StructConverterUtil.toDataType( this );
    +//	}
    +
    +}
    
  • GPL/DMG/src/dmg/java/mobiledevices/dmg/btree/BTreeMapRecord.java+47 0 added
    @@ -0,0 +1,47 @@
    +/* ###
    + * IP: Public Domain
    + */
    +package mobiledevices.dmg.btree;
    +
    +import java.io.IOException;
    +
    +import mobiledevices.dmg.ghidra.GBinaryReader;
    +
    +/**
    + * Represents a Map Record.
    + * 
    + * @see <a href="https://developer.apple.com/library/archive/technotes/tn/tn1150.html">Map Record</a> 
    + */
    +public class BTreeMapRecord /*implements StructConverter*/ {
    +
    +	private byte[] bitmap;
    +
    +	protected BTreeMapRecord(GBinaryReader reader, BTreeHeaderRecord headerRecord)
    +			throws IOException {
    +		this.bitmap = reader.readNextByteArray(headerRecord.getNodeSize() - 256);
    +	}
    +
    +	/**
    +	 * Returns the map record node allocation bitmap.
    +	 * @return the map record node allocation bitmap
    +	 */
    +	public byte[] getBitmap() {
    +		return bitmap;
    +	}
    +
    +	/**
    +	 * Returns  true if the specified node index is used.
    +	 * Returns false if the specified node index is free.
    +	 * @param nodeIndex the node index
    +	 * @return true if the specified node index is used, false if free
    +	 */
    +	public boolean isNodeUsed(int nodeIndex) {
    +		int block = bitmap[nodeIndex / 8] & 0xff;
    +		return (block & (1 << 7 - (nodeIndex % 8))) != 0;
    +	}
    +
    +//	@Override
    +//	public DataType toDataType() throws DuplicateNameException, IOException {
    +//		return StructConverterUtil.toDataType( this );
    +//	}
    +}
    
  • GPL/DMG/src/dmg/java/mobiledevices/dmg/btree/BTreeNodeDescriptor.java+128 0 added
    @@ -0,0 +1,128 @@
    +/* ###
    + * IP: Public Domain
    + */
    +package mobiledevices.dmg.btree;
    +
    +import java.io.IOException;
    +import java.util.ArrayList;
    +import java.util.List;
    +
    +import mobiledevices.dmg.ghidra.GBinaryReader;
    +
    +/**
    + * Represents a BTNodeDescriptor structure.
    + * 
    + * @see <a href="https://opensource.apple.com/source/xnu/xnu-792/bsd/hfs/hfs_format.h.auto.html">hfs/hfs_format.h</a> 
    + */
    +public class BTreeNodeDescriptor /*implements StructConverter*/ {
    +
    +	private int fLink;
    +	private int bLink;
    +	private byte kind;
    +	private byte height;
    +	private short numRecords;
    +	private short reserved;
    +
    +	private List<Short> _recordOffsets = new ArrayList<Short>();
    +	private List<BTreeNodeRecord> _records = new ArrayList<BTreeNodeRecord>();
    +
    +	BTreeNodeDescriptor(GBinaryReader reader) throws IOException {
    +		this.fLink = reader.readNextInt();
    +		this.bLink = reader.readNextInt();
    +		this.kind = reader.readNextByte();
    +		this.height = reader.readNextByte();
    +		this.numRecords = reader.readNextShort();
    +		this.reserved = reader.readNextShort();
    +	}
    +
    +	protected void readRecordOffsets(GBinaryReader reader, long nodeStartIndex,
    +			BTreeHeaderRecord header) throws IOException {
    +		long position = nodeStartIndex + header.getNodeSize() - 2;
    +		while (true) {
    +			short recordOffset = reader.readShort(position);
    +			if (recordOffset == 0) {
    +				break;
    +			}
    +			_recordOffsets.add(recordOffset);
    +			position = position - 2;
    +		}
    +	}
    +
    +	protected void readRecords(GBinaryReader reader, long nodeStartIndex) throws IOException {
    +		for (int i = 0; i < getNumRecords(); ++i) {
    +
    +			short offset = getRecordOffsets().get(i);
    +
    +			long recordIndex = (offset & 0xffff) + nodeStartIndex;
    +			reader.setPointerIndex(recordIndex);
    +
    +			BTreeNodeRecord record = new BTreeNodeRecord(reader, this);
    +			_records.add(record);
    +		}
    +	}
    +
    +	public List<Short> getRecordOffsets() {
    +		return _recordOffsets;
    +	}
    +
    +	public List<BTreeNodeRecord> getRecords() {
    +		return _records;
    +	}
    +
    +	/**
    +	 * The node number of the next node of this type.
    +	 * Or, zero ( 0 ) if this is the last node.
    +	 * @return node number of the next node of this type
    +	 */
    +	public int getFLink() {
    +		return fLink;
    +	}
    +
    +	/**
    +	 * The node number of the previous node of this type.
    +	 * Or, zero ( 0 ) if this is the first node.
    +	 * @return node number of the previous node of this type
    +	 */
    +	public int getBLink() {
    +		return bLink;
    +	}
    +
    +	/**
    +	 * Returns the key of this node.
    +	 * @return the key of this node
    +	 * @see BTreeNodeKinds
    +	 */
    +	public byte getKind() {
    +		return kind;
    +	}
    +
    +	/**
    +	 * Returns the level, or depth, of this node in the B-tree hierarchy.
    +	 * @return the level, or depth, of this node in the B-tree hierarchy
    +	 */
    +	public byte getHeight() {
    +		return height;
    +	}
    +
    +	/**
    +	 * Returns the number of records in this node.
    +	 * @return the number of records in this node
    +	 */
    +	public short getNumRecords() {
    +		return numRecords;
    +	}
    +
    +	/**
    +	 * This field is reserved.
    +	 * @return this field is reserved
    +	 */
    +	public short getReserved() {
    +		return reserved;
    +	}
    +
    +//	@Override
    +//	public DataType toDataType() throws DuplicateNameException, IOException {
    +//		return StructConverterUtil.toDataType( this );
    +//	}
    +
    +}
    
  • GPL/DMG/src/dmg/java/mobiledevices/dmg/btree/BTreeNodeKinds.java+19 0 added
    @@ -0,0 +1,19 @@
    +/* ###
    + * IP: Public Domain
    + */
    +package mobiledevices.dmg.btree;
    +
    +/**
    + * Represents kinds of BTNodeDescriptor.
    + * 
    + * @see <a href="https://opensource.apple.com/source/xnu/xnu-792/bsd/hfs/hfs_format.h.auto.html">hfs/hfs_format.h</a>
    + * @see <a href="https://developer.apple.com/library/archive/technotes/tn/tn1150.html">B-Trees</a> 
    + */
    +public final class BTreeNodeKinds {
    +
    +	public final static byte kBTLeafNode = -1;
    +	public final static byte kBTIndexNode = 0;
    +	public final static byte kBTHeaderNode = 1;
    +	public final static byte kBTMapNode = 2;
    +
    +}
    
  • GPL/DMG/src/dmg/java/mobiledevices/dmg/btree/BTreeNodeRecord.java+140 0 added
    @@ -0,0 +1,140 @@
    +/* ###
    + * IP: Public Domain
    + */
    +package mobiledevices.dmg.btree;
    +
    +import java.io.IOException;
    +
    +import mobiledevices.dmg.decmpfs.DecmpfsHeader;
    +import mobiledevices.dmg.ghidra.GBinaryReader;
    +import mobiledevices.dmg.xattr.XattrConstants;
    +
    +public class BTreeNodeRecord /*implements StructConverter*/ {
    +
    +	private int    unknown0;
    +	private int    fileID;
    +	private int    unknown2;
    +	private String type;
    +	private int    unknown3;
    +	private int    unknown4;
    +	private int    unknown5;
    +	private int    recordLength;
    +
    +	private short _typeLength;
    +	private BTreeNodeDescriptor _descriptor;
    +	private DecmpfsHeader _decmpfsHeader;
    +	private long _offset;
    +
    +	BTreeNodeRecord( GBinaryReader reader, BTreeNodeDescriptor descriptor ) throws IOException {
    +		_offset       =  reader.getPointerIndex();
    +
    +		unknown0      =  reader.readNextInt();
    +		fileID        =  reader.readNextInt();
    +		unknown2      =  reader.readNextInt();
    +
    +		_typeLength   =  reader.readNextShort();
    +
    +		type          =  readType( reader );
    +		unknown3      =  reader.readNextInt();
    +
    +		switch ( descriptor.getKind() ) {
    +			case BTreeNodeKinds.kBTHeaderNode: {
    +				break;
    +			}
    +			case BTreeNodeKinds.kBTIndexNode: {
    +				break;
    +			}
    +			case BTreeNodeKinds.kBTLeafNode: {
    +				unknown4      =  reader.readNextInt();
    +				unknown5      =  reader.readNextInt();
    +				recordLength  =  reader.readNextInt();
    +				break;
    +			}
    +			case BTreeNodeKinds.kBTMapNode: {
    +				break;
    +			}
    +		}
    +
    +		_descriptor = descriptor;
    +
    +		if ( descriptor.getKind() == BTreeNodeKinds.kBTLeafNode ) {
    +			if ( getType().equals( XattrConstants.DECMPFS_XATTR_NAME ) ) {
    +				_decmpfsHeader = new DecmpfsHeader( reader, getRecordLength() );
    +			}
    +			else if ( getType().equals( XattrConstants.KAUTH_FILESEC_XATTR_NAME ) ) {
    +				//TODO
    +			}
    +		}
    +		else if ( descriptor.getKind() == BTreeNodeKinds.kBTIndexNode ) {
    +			if ( getType().equals( XattrConstants.DECMPFS_XATTR_NAME ) ) {
    +				//TODO
    +			}
    +		}
    +	}
    +
    +	private String readType( GBinaryReader reader ) throws IOException {
    +		StringBuffer buffer = new StringBuffer();
    +		for ( int i = 0 ; i < _typeLength ; ++i ) {
    +			reader.readNextByte();//skip it...
    +			buffer.append( (char) reader.readNextByte() );
    +		}
    +		return buffer.toString();
    +	}
    +
    +	public String getType() {
    +		return type;
    +	}
    +	public int getRecordLength() {
    +		return recordLength;
    +	}
    +	public BTreeNodeDescriptor getDescriptor() {
    +		return _descriptor;
    +	}
    +	public int getUnknown0() {
    +		return unknown0;
    +	}
    +	public int getUnknown2() {
    +		return unknown2;
    +	}
    +	public int getUnknown3() {
    +		return unknown3;
    +	}
    +	public int getUnknown4() {
    +		return unknown4;
    +	}
    +	public int getUnknown5() {
    +		return unknown5;
    +	}
    +	public int getFileID() {
    +		return fileID;
    +	}
    +	public DecmpfsHeader getDecmpfsHeader() {
    +		return _decmpfsHeader;
    +	}
    +	public long getRecordOffset() {
    +		return _offset;
    +	}
    +
    +//	@Override
    +//	public DataType toDataType() throws DuplicateNameException, IOException {
    +//		String name = StructConverterUtil.parseName( BTreeNodeRecord.class );
    +//		Structure struct = new StructureDataType( name, 0 );
    +//		struct.add( DWORD, "unknown0", null );
    +//		struct.add( DWORD, "fileID", null );
    +//		struct.add( DWORD, "unknown2", null );
    +//		struct.add(  WORD, "typeLength", null );
    +//		struct.add( UNICODE, _typeLength * 2, "type", null );
    +//		struct.add( DWORD, "unknown3", null );
    +//		if ( _descriptor.getKind() == BTreeNodeKinds.kBTLeafNode ) {
    +//			struct.add( DWORD, "unknown4", null );
    +//			struct.add( DWORD, "unknown5", null );
    +//			struct.add( DWORD, "recordLength", null );
    +//		}
    +//		try {
    +//			struct.setName( name + '_' + struct.getLength() );
    +//		}
    +//		catch ( Exception e ) {
    +//		}
    +//		return struct;
    +//	}
    +}
    
  • GPL/DMG/src/dmg/java/mobiledevices/dmg/btree/BTreeRootNodeDescriptor.java+72 0 added
    @@ -0,0 +1,72 @@
    +/* ###
    + * IP: Public Domain
    + */
    +package mobiledevices.dmg.btree;
    +
    +import java.io.IOException;
    +import java.util.ArrayList;
    +import java.util.List;
    +
    +import mobiledevices.dmg.ghidra.GBinaryReader;
    +
    +public class BTreeRootNodeDescriptor extends BTreeNodeDescriptor {
    +
    +	private BTreeHeaderRecord headerRecord;
    +	private BTreeUserDataRecord userDataRecord;
    +	private BTreeMapRecord mapRecord;
    +	private List<BTreeNodeDescriptor> nodes = new ArrayList<BTreeNodeDescriptor>();
    +
    +	public BTreeRootNodeDescriptor( GBinaryReader reader ) throws IOException {
    +		super( reader );
    +
    +		headerRecord   = new BTreeHeaderRecord( reader );
    +		userDataRecord = new BTreeUserDataRecord( reader );
    +		mapRecord      = new BTreeMapRecord( reader, headerRecord );
    +
    +		nodes.add( this );
    +
    +		int nodeSize = headerRecord.getNodeSize() & 0xffff;
    +
    +		for ( int i = nodeSize ; i < reader.length() ; i += nodeSize ) {
    +			reader.setPointerIndex( i );
    +			BTreeNodeDescriptor node = new BTreeNodeDescriptor( reader );
    +			nodes.add( node );
    +			node.readRecordOffsets( reader, i, headerRecord );
    +			node.readRecords( reader, i );
    +		}
    +
    +		this.readRecordOffsets( reader, 0, headerRecord );
    +	}
    +
    +	public BTreeHeaderRecord getHeaderRecord() {
    +		return headerRecord;
    +	}
    +
    +	public BTreeUserDataRecord getUserDataRecord() {
    +		return userDataRecord;
    +	}
    +
    +	public BTreeMapRecord getMapRecord() {
    +		return mapRecord;
    +	}
    +
    +	public BTreeNodeDescriptor getNode( int index ) {
    +		try {
    +			return nodes.get( index );
    +		}
    +		catch (Exception e) {
    +			return null;
    +		}
    +	}
    +
    +	public List<BTreeNodeDescriptor> getNodes() {
    +		return nodes;
    +	}
    +
    +//	@Override
    +//	public DataType toDataType() throws DuplicateNameException, IOException {
    +//		//we want to return the super class structure,
    +//		//this class is synthetic
    +//		return StructConverterUtil.toDataType( BTreeNodeDescriptor.class );
    +//	}
    +}
    
  • GPL/DMG/src/dmg/java/mobiledevices/dmg/btree/BTreeTypes.java+14 0 added
    @@ -0,0 +1,14 @@
    +/* ###
    + * IP: Public Domain
    + */
    +package mobiledevices.dmg.btree;
    +
    +public final class BTreeTypes {
    +
    +	/** Control file */
    +	public final static byte kHFSBTreeType       =  (byte)0;
    +	/** User bTree types start from 128 */
    +	public final static byte kUserBTreeType      =  (byte)128;
    +	/** */
    +	public final static byte kReservedBTreeType  =  (byte)255;
    +}
    
  • GPL/DMG/src/dmg/java/mobiledevices/dmg/btree/BTreeUserDataRecord.java+31 0 added
    @@ -0,0 +1,31 @@
    +/* ###
    + * IP: Public Domain
    + */
    +package mobiledevices.dmg.btree;
    +
    +import java.io.IOException;
    +
    +import mobiledevices.dmg.ghidra.GBinaryReader;
    +
    +/**
    + * Represents a User Data Record.
    + * 
    + * @see <a href="https://developer.apple.com/library/archive/technotes/tn/tn1150.html">User Data Record</a> 
    + */
    +public class BTreeUserDataRecord /*implements StructConverter*/ {
    +
    +	private byte[] unused;
    +
    +	BTreeUserDataRecord(GBinaryReader reader) throws IOException {
    +		this.unused = reader.readNextByteArray(128);
    +	}
    +
    +	public byte[] getUnused() {
    +		return unused;
    +	}
    +
    +//	@Override
    +//	public DataType toDataType() throws DuplicateNameException, IOException {
    +//		return StructConverterUtil.toDataType( this );
    +//	}
    +}
    
  • GPL/DMG/src/dmg/java/mobiledevices/dmg/decmpfs/DecmpfsCompressionTypes.java+22 0 added
    @@ -0,0 +1,22 @@
    +/* ###
    + * IP: Public Domain
    + */
    +package mobiledevices.dmg.decmpfs;
    +
    +public final class DecmpfsCompressionTypes {
    +
    +	/** Uncompressed data in xattr. */
    +	public final static int CMP_Type1   = 1;
    +
    +	/** Data stored in-line. */
    +	public final static int CMP_Type3   = 3;
    +
    +	/** Resource fork contains compressed data. */
    +	public final static int CMP_Type4   = 4;
    +
    +	/** ???? */
    +	public final static int CMP_Type10  = 10;
    +
    +	public final static int CMP_MAX     = 255;
    +
    +}
    
  • GPL/DMG/src/dmg/java/mobiledevices/dmg/decmpfs/DecmpfsConstants.java+13 0 added
    @@ -0,0 +1,13 @@
    +/* ###
    + * IP: Public Domain
    + */
    +package mobiledevices.dmg.decmpfs;
    +
    +public final class DecmpfsConstants {
    +
    +	public final static int MAX_DECMPFS_XATTR_SIZE  =  3802;
    +
    +	public final static byte [] DECMPFS_MAGIC_BYTES  =  { 'f', 'p', 'm', 'c' };
    +	public final static String  DECMPFS_MAGIC        =  new String( DECMPFS_MAGIC_BYTES );
    +	
    +}
    
  • GPL/DMG/src/dmg/java/mobiledevices/dmg/decmpfs/DecmpfsHeader.java+79 0 added
    @@ -0,0 +1,79 @@
    +/* ###
    + * IP: Public Domain
    + */
    +package mobiledevices.dmg.decmpfs;
    +
    +import java.io.IOException;
    +
    +import mobiledevices.dmg.ghidra.GBinaryReader;
    +import mobiledevices.dmg.ghidra.GStringUtilities;
    +
    +public class DecmpfsHeader /*implements StructConverter*/ {
    +	private int     compression_magic;
    +	private int     compression_type;
    +	private long    uncompressed_size;
    +	private byte [] attr_bytes;
    +
    +	public DecmpfsHeader(GBinaryReader reader, int size) throws IOException {
    +		long index = reader.getPointerIndex();
    +
    +		this.compression_magic = reader.readNextInt();
    +
    +		boolean originalEndian = reader.isLittleEndian();
    +		reader.setLittleEndian( true );
    +
    +		this.compression_type  = reader.readNextInt();
    +		this.uncompressed_size = reader.readNextLong();
    +
    +		reader.setLittleEndian( originalEndian );
    +
    +		long endIndex = index + size + 1; //TODO always add 1????
    +
    +		if ( ( endIndex % 2 ) != 0 ) {
    +			endIndex = endIndex - 1;
    +		}
    +
    +		long nElements = endIndex - reader.getPointerIndex();
    +
    +if ( ( nElements % 2 ) != 0 ) {//TODO
    +	++nElements;
    +}
    +else if ( nElements < 0 ) {//TODO
    +	System.err.println( "here" );
    +}
    +		this.attr_bytes = reader.readNextByteArray( (int)nElements );
    +	}
    +
    +	public String getCompressionMagic() {
    +		return GStringUtilities.toString( compression_magic );
    +	}
    +
    +	public int getCompressionType() {
    +		return compression_type;
    +	}
    +
    +	public long getUncompressedSize() {
    +		return uncompressed_size;
    +	}
    +
    +	public byte [] getAttrBytes() {
    +		return attr_bytes;
    +	}
    +
    +//	@Override
    +//	public DataType toDataType() throws DuplicateNameException, IOException {
    +//		String name = StructConverterUtil.parseName( DecmpfsHeader.class );
    +//		Structure struct = new StructureDataType( name + "_" + attr_bytes.length, 0 );
    +//
    +//		struct.add( STRING, 4, "compression_magic", null );
    +//		struct.add( DWORD,     "compression_type",  null );
    +//		struct.add( QWORD,     "uncompressed_size", null );
    +//
    +//		if ( attr_bytes.length > 0 ) {
    +//			ArrayDataType byteArrayDT = new ArrayDataType( BYTE , attr_bytes.length, BYTE.getLength() );
    +//			struct.add( byteArrayDT, "attr_bytes", null );
    +//		}
    +//		return struct;
    +//	}
    +	
    +}
    
  • GPL/DMG/src/dmg/java/mobiledevices/dmg/decmpfs/DecmpfsStates.java+13 0 added
    @@ -0,0 +1,13 @@
    +/* ###
    + * IP: Public Domain
    + */
    +package mobiledevices.dmg.decmpfs;
    +
    +public final class DecmpfsStates {
    +
    +	public final static int FILE_TYPE_UNKNOWN = 0;
    +	public final static int FILE_IS_NOT_COMPRESSED = 1;
    +	public final static int FILE_IS_COMPRESSED = 2;
    +	public final static int FILE_IS_CONVERTING = 3; //file is converting from compressed to decompressed...
    +
    +}
    
  • GPL/DMG/src/dmg/java/mobiledevices/dmg/ghidra/GBinaryReader.java+957 0 added
    @@ -0,0 +1,957 @@
    +/* ###
    + * IP: Public Domain
    + */
    +package mobiledevices.dmg.ghidra;
    +
    +import java.io.IOException;
    +
    +/**
    + * A class for reading data from a 
    + * generic byte provider in either big-endian or little-endian.
    + * 
    + * 
    + */
    +public class GBinaryReader {
    +    /**
    +     * The size of a BYTE in Java.
    +     */
    +    public final static int SIZEOF_BYTE = 1;
    +    /**
    +     * The size of a SHORT in Java.
    +     */
    +    public final static int SIZEOF_SHORT = 2;
    +    /**
    +     * The size of an INTEGER in Java.
    +     */
    +    public final static int SIZEOF_INT = 4;
    +    /**
    +     * The size of a LONG in Java.
    +     */
    +    public final static int SIZEOF_LONG = 8;
    +
    +    private GByteProvider provider;
    +    private GDataConverter converter;
    +    private long currentIndex;
    +
    +    /**
    +     * Constructs a reader using the given 
    +     * file and endian-order.
    +     * 
    +     * If isLittleEndian is true, then all values read
    +     * from the file will be done so assuming
    +     * little-endian order.
    +     * 
    +     * Otherwise, if isLittleEndian
    +     * is false, then all values will be read
    +     * assuming big-endian order.
    +     * 
    +     * @param provider the byte provider
    +     * @param isLittleEndian the endian-order
    +     */
    +    public GBinaryReader(GByteProvider provider, boolean isLittleEndian) {
    +        this.provider = provider;
    +        setLittleEndian(isLittleEndian);
    +    }
    +
    +    /**
    +     * Returns a clone of this reader positioned at the new index.
    +     * @param newIndex the new index
    +     * @return a clone of this reader positioned at the new index
    +     */
    +    public GBinaryReader clone(int newIndex) {
    +    	GBinaryReader clone = new GBinaryReader(provider, isLittleEndian());
    +    	clone.converter = converter;
    +    	clone.currentIndex = newIndex;
    +    	return clone;
    +    }
    +
    +    /**
    +     * Returns true if this reader will extract values in little endian,
    +     * otherwise in big endian.
    +     * @return true is little endian, false is big endian
    +     */
    +	public boolean isLittleEndian() {
    +		return converter instanceof GDataConverterLE;
    +	}
    +
    +	/**
    +	 * Sets the endian of this binary reader.
    +	 * @param isLittleEndian true for little-endian and false for big-endian
    +	 */
    +	public void setLittleEndian(boolean isLittleEndian) {
    +        if (isLittleEndian) {
    +            converter = new GDataConverterLE();
    +        }
    +        else {
    +            converter = new GDataConverterBE();
    +        }
    +	}
    +
    +    /**
    +     * Returns the length of the underlying file.
    +     * @return returns the length of the underlying file
    +     * @exception IOException if an I/O error occurs
    +     */
    +    public long length() throws IOException {
    +        return provider.length();
    +    }
    +
    +    /**
    +     * Returns true if the specified index into 
    +     * the underlying byte provider is valid.
    +     * @param index the index in the byte provider
    +     * @return returns true if the specified index is valid
    +     * @exception IOException if an I/O error occurs
    +     */
    +    public boolean isValidIndex(int index) throws IOException {
    +        return provider.isValidIndex(index & GConv.INT_MASK);
    +    }
    +
    +    /**
    +     * Returns true if the specified index into 
    +     * the underlying byte provider is valid.
    +     * @param index the index in the byte provider
    +     * @return returns true if the specified index is valid
    +     * @exception IOException if an I/O error occurs
    +     */
    +    public boolean isValidIndex(long index) throws IOException {
    +        return provider.isValidIndex(index);
    +    }
    +
    +    /**
    +     * Aligns the current index on the specified alignment value.
    +     * For example, if current index was 123 and align value was
    +     * 16, then current index would become 128.
    +     * @param alignValue
    +     * @return the number of bytes required to align
    +     */
    +    public int align(int alignValue) {
    +        long align = currentIndex % alignValue;
    +        if (align == 0) {
    +            return 0;
    +        }
    +        currentIndex = currentIndex + (alignValue - align);
    +        return (int)(alignValue - align);
    +    }
    +
    +    ////////////////////////////////////////////////////////////////////
    +
    +    /**
    +     * A convenience method for setting the index using
    +     * an integer.
    +     */
    +    public void setPointerIndex(int index) {
    +        this.currentIndex = index & GConv.INT_MASK;
    +    }
    +
    +    /**
    +     * Sets the current index to the specified value.
    +     * The pointer index will allow the reader
    +     * to operate as a psuedo-iterator.
    +     * 
    +     * @param index the byte provider index value
    +     */
    +    public void setPointerIndex(long index) {
    +        this.currentIndex = index;
    +    }
    +
    +    /**
    +     * Returns the current index value.
    +     * @return the current index value
    +     */
    +    public long getPointerIndex() {
    +        return currentIndex;
    +    }
    +
    +    /**
    +     * Peeks at the next byte without incrementing
    +     * the current index.
    +     * @return the next byte
    +     * @exception IOException if an I/O error occurs
    +     */
    +    public byte peekNextByte() throws IOException {
    +        return readByte(currentIndex);
    +    }
    +
    +    /**
    +     * Peeks at the next short without incrementing
    +     * the current index.
    +     * @return the next short
    +     * @exception IOException if an I/O error occurs
    +     */
    +    public short peekNextShort() throws IOException {
    +        return readShort(currentIndex);
    +    }
    +
    +    /**
    +     * Peeks at the next integer without incrementing
    +     * the current index.
    +     * @return the next int
    +     * @exception IOException if an I/O error occurs
    +     */
    +    public int peekNextInt() throws IOException {
    +        return readInt(currentIndex);
    +    }
    +
    +    /**
    +     * Peeks at the next long without incrementing
    +     * the current index.
    +     * @return the next long
    +     * @exception IOException if an I/O error occurs
    +     */
    +    public long peekNextLong() throws IOException {
    +        return readLong(currentIndex);
    +    }
    +
    +    /**
    +     * Reads the byte at the current index and then increments the current
    +     * index by <code>SIZEOF_BYTE</code>.
    +     * @return the byte at the current index
    +     * @exception IOException if an I/O error occurs
    +     */
    +    public byte readNextByte() throws IOException {
    +        byte b = readByte(currentIndex);
    +        currentIndex += SIZEOF_BYTE;
    +        return b;
    +    }
    +
    +    /**
    +     * Reads the byte at the current index and then increments the current
    +     * index by <code>SIZEOF_BYTE</code>.
    +     * @return the byte at the current index
    +     * @exception IOException if an I/O error occurs
    +     */
    +    public byte readNextByte(byte minClamp, byte maxClamp, Byte... exceptions) throws IOException {
    +        byte b = readByte(currentIndex, minClamp, maxClamp, exceptions);
    +        currentIndex += SIZEOF_BYTE;
    +        return b;
    +    }
    +
    +    /**
    +     * Reads the short at the current index and then increments the current
    +     * index by <code>SIZEOF_SHORT</code>.
    +     * @return the short at the current index
    +     * @exception IOException if an I/O error occurs
    +     */
    +    public short readNextShort() throws IOException {
    +        short s = readShort(currentIndex);
    +        currentIndex+=SIZEOF_SHORT;
    +        return s;
    +    }
    +
    +    /**
    +     * Reads the short at the current index and then increments the current
    +     * index by <code>SIZEOF_SHORT</code>.
    +     * @return the short at the current index
    +     * @exception IOException if an I/O error occurs
    +     */
    +    public short readNextShort(short minClamp, short maxClamp, Short... exceptions) throws IOException {
    +        short s = readShort(currentIndex, minClamp, maxClamp, exceptions);
    +        currentIndex+=SIZEOF_SHORT;
    +        return s;
    +    }
    +
    +    /**
    +     * Reads the integer at the current index and then increments the current
    +     * index by <code>SIZEOF_INT</code>.
    +     * @return the integer at the current index
    +     * @exception IOException if an I/O error occurs
    +     */
    +    public int readNextInt() throws IOException {
    +        int i = readInt(currentIndex);
    +        currentIndex+=SIZEOF_INT;
    +        return i;
    +    }
    +
    +    /**
    +     * Reads the integer at the current index and then increments the current
    +     * index by <code>SIZEOF_INT</code>.
    +     * @return the integer at the current index
    +     * @exception IOException if an I/O error occurs
    +     */
    +    public int readNextInt(int minClamp, int maxClamp, Integer... exceptions) throws IOException {
    +        int i = readInt(currentIndex, minClamp, maxClamp, exceptions);
    +        currentIndex+=SIZEOF_INT;
    +        return i;
    +    }
    +
    +    /**
    +     * Reads the long at the current index and then increments the current
    +     * index by <code>SIZEOF_LONG</code>.
    +     * @return the long at the current index
    +     * @exception IOException if an I/O error occurs
    +     */
    +    public long readNextLong() throws IOException {
    +        long l = readLong(currentIndex);
    +        currentIndex+=SIZEOF_LONG;
    +        return l;
    +    }
    +
    +    /**
    +     * Reads the long at the current index and then increments the current
    +     * index by <code>SIZEOF_LONG</code>.
    +     * @return the long at the current index
    +     * @exception IOException if an I/O error occurs
    +     */
    +    public long readNextLong(long minClamp, long maxClamp, Long... exceptions) throws IOException {
    +        long l = readLong(currentIndex, minClamp, maxClamp, exceptions);
    +        currentIndex+=SIZEOF_LONG;
    +        return l;
    +    }
    +
    +    /**
    +     * Reads the Ascii string at the current index and then increments the current
    +     * index by the length of the Ascii string that was found. This method
    +     * expects the string to be null-terminated.
    +     * @return the null-terminated Ascii string at the current index
    +     * @exception IOException if an I/O error occurs
    +     */
    +    public String readNextAsciiString() throws IOException {
    +        String s = readAsciiString(currentIndex);
    +        currentIndex+=(s.length()+1);
    +        return s;
    +    }
    +
    +    /**
    +     * Reads an Ascii string of <code>length</code>
    +     * characters starting at the current index and then increments the current
    +     * index by <code>length</code>.
    +     * 
    +     * @return the Ascii string at the current index
    +     */
    +    public String readNextAsciiString(int length) throws IOException {
    +        String s = readAsciiString(currentIndex, length);
    +        currentIndex+=length;
    +        return s;
    +    }
    +
    +    /**
    +     * Reads the Unicode string at the current index and then increments the current
    +     * index by the length of the Unicode string that was found. This method
    +     * expects the string to be double null-terminated ('\0\0').
    +     * @return the null-terminated Ascii string at the current index
    +     * @exception IOException if an I/O error occurs
    +     */
    +    public String readNextUnicodeString() throws IOException {
    +        String s = readUnicodeString(currentIndex);
    +        currentIndex += ((s.length()+1)*2);
    +        return s;
    +    }
    +
    +    /**
    +     * Reads the unicode string at the current index and then increments the current
    +     * index by <code>length</code>.
    +     * @return the unicode string at the current index
    +     * @exception IOException if an I/O error occurs
    +     */
    +    public String readNextUnicodeString(int length) throws IOException {
    +        String s = readUnicodeString(currentIndex, length);
    +        currentIndex+=(length*2);
    +        return s;
    +    }
    +
    +    /**
    +     * Reads a byte array of <code>nElements</code>
    +     * starting at the current index and then increments the current
    +     * index by <code>SIZEOF_BYTE * nElements</code>.
    +     * @return the byte array starting at the current index
    +     * @exception IOException if an I/O error occurs
    +     */
    +    public byte [] readNextByteArray(int nElements) throws IOException {
    +        byte [] b = readByteArray(currentIndex, nElements);
    +        currentIndex+=(SIZEOF_BYTE*nElements);
    +        return b;
    +    }
    +
    +    /**
    +     * Reads a byte array of <code>nElements</code>
    +     * starting at the current index and then increments the current
    +     * index by <code>SIZEOF_BYTE * nElements</code>.
    +     * @return the byte array starting at the current index
    +     * @exception IOException if an I/O error occurs
    +     */
    +    public byte [] readNextByteArray(int nElements, byte minClamp, byte maxClamp, Byte... exceptions) throws IOException {
    +        byte [] b = readByteArray(currentIndex, nElements, minClamp, maxClamp, exceptions);
    +        currentIndex+=(SIZEOF_BYTE*nElements);
    +        return b;
    +    }
    +
    +    /**
    +     * Reads a short array of <code>nElements</code>
    +     * starting at the current index and then increments the current
    +     * index by <code>SIZEOF_SHORT * nElements</code>.
    +     * @return the short array starting at the current index
    +     * @exception IOException if an I/O error occurs
    +     */
    +    public short [] readNextShortArray(int nElements) throws IOException {
    +        short [] s = readShortArray(currentIndex, nElements);
    +        currentIndex+=(SIZEOF_SHORT*nElements);
    +        return s;
    +    }
    +
    +    /**
    +     * Reads a short array of <code>nElements</code>
    +     * starting at the current index and then increments the current
    +     * index by <code>SIZEOF_SHORT * nElements</code>.
    +     * @return the short array starting at the current index
    +     * @exception IOException if an I/O error occurs
    +     */
    +    public short [] readNextShortArray(int nElements, short minClamp, short maxClamp, Short... exceptions) throws IOException {
    +        short [] s = readShortArray(currentIndex, nElements, minClamp, maxClamp, exceptions);
    +        currentIndex+=(SIZEOF_SHORT*nElements);
    +        return s;
    +    }
    +
    +    /**
    +     * Reads an integer array of <code>nElements</code>
    +     * starting at the current index and then increments the current
    +     * index by <code>SIZEOF_INT * nElements</code>.
    +     * @return the integer array starting at the current index
    +     * @exception IOException if an I/O error occurs
    +     */
    +    public int [] readNextIntArray(int nElements) throws IOException {
    +        int [] i = readIntArray(currentIndex, nElements);
    +        currentIndex+=(SIZEOF_INT*nElements);
    +        return i;
    +    }
    +
    +    /**
    +     * Reads an integer array of <code>nElements</code>
    +     * starting at the current index and then increments the current
    +     * index by <code>SIZEOF_INT * nElements</code>.
    +     * @return the integer array starting at the current index
    +     * @exception IOException if an I/O error occurs
    +     */
    +    public int [] readNextIntArray(int nElements, int minClamp, int maxClamp, Integer... exceptions) throws IOException {
    +        int [] i = readIntArray(currentIndex, nElements, minClamp, maxClamp, exceptions);
    +        currentIndex+=(SIZEOF_INT*nElements);
    +        return i;
    +    }
    +
    +    /**
    +     * Reads a long array of <code>nElements</code>
    +     * starting at the current index and then increments the current
    +     * index by <code>SIZEOF_LONG * nElements</code>.
    +     * @return the long array starting at the current index
    +     * @exception IOException if an I/O error occurs
    +     */
    +    public long [] readNextLongArray(int nElements) throws IOException {
    +        long [] l = readLongArray(currentIndex, nElements);
    +        currentIndex+=(SIZEOF_LONG*nElements);
    +        return l;
    +    }
    +
    +    /**
    +     * Reads a long array of <code>nElements</code>
    +     * starting at the current index and then increments the current
    +     * index by <code>SIZEOF_LONG * nElements</code>.
    +     * @return the long array starting at the current index
    +     * @exception IOException if an I/O error occurs
    +     */
    +    public long [] readNextLongArray(int nElements, long minClamp, long maxClamp, Long... exceptions) throws IOException {
    +        long [] l = readLongArray(currentIndex, nElements, minClamp, maxClamp, exceptions);
    +        currentIndex+=(SIZEOF_LONG*nElements);
    +        return l;
    +    }
    +
    +    ////////////////////////////////////////////////////////////////////
    +
    +    /**
    +     * Returns a null-terminated Ascii string starting
    +     * at <code>index</code>. The end of the string
    +     * is denoted by a <code>null</code> character.
    +     * 
    +     * @param index the index where the Ascii string begins
    +     * @return the Ascii string
    +     * @exception IOException if an I/O error occurs
    +     */
    +    public String readAsciiString(long index) throws IOException {
    +        StringBuffer buffer = new StringBuffer();
    +        while (true) {
    +            byte b = provider.readByte(index++);
    +            if ((b >= 32) && (b <= 126)) {
    +                buffer.append((char)b);
    +            }
    +            else {
    +                break;
    +            }
    +        }
    +        return buffer.toString().trim();
    +    }
    +
    +    /**
    +     * Returns an Ascii string of <code>length</code> bytes
    +     * starting at <code>index</code>. This method does not
    +     * care about null-terminators.
    +     * @param index the index where the Ascii string begins
    +     * @param length the length of the Ascii string
    +     * @return the Ascii string
    +     * @exception IOException if an I/O error occurs
    +     */
    +    public String readAsciiString(long index, int length) throws IOException {
    +        StringBuffer buffer = new StringBuffer();
    +        for (int i = 0 ; i < length ; ++i) {
    +            byte b = provider.readByte(index++);
    +            buffer.append((char) (b & 0x00FF));
    +        }
    +        return buffer.toString().trim();
    +    }
    +
    +    /**
    +     * Returns a null-terminated Unicode string starting
    +     * at <code>index</code>. The end of the string
    +     * is denoted by two-byte Unicode <code>null</code> character.
    +     * @param index the index where the Unicode string begins
    +     * @return the Unicode string
    +     * @exception IOException if an I/O error occurs
    +     */
    +    public String readUnicodeString(long index) throws IOException {
    +        StringBuffer buffer = new StringBuffer();
    +		char c = 0;
    +		int i = 0;
    +        while (i < length()) {
    +            c  = (char)((provider.readByte(index++) & 0xff));
    +            c += (char)((provider.readByte(index++) & 0xff) << 8);
    +            if (c == 0x0000) {
    +                break;
    +            }
    +            buffer.append(c); 
    +            i += 2;
    +        }
    +        return buffer.toString().trim();
    +    }
    +
    +    /**
    +     * Returns a Unicode string of <code>length</code> bytes
    +     * starting at <code>index</code>. This method does not
    +     * care about null-terminators.
    +     * @param index the index where the Unicode string begins
    +     * @param length the length of the Unicode string
    +     * @return the Unicode string
    +     * @exception IOException if an I/O error occurs
    +     */
    +    public String readUnicodeString(long index, int length) throws IOException {
    +        StringBuffer buffer = new StringBuffer();
    +        char c = 0;
    +        for (int i = 0 ; i < length*2 ; i+=2) {
    +            c  = (char)((provider.readByte(index++) & 0xff));
    +            c += (char)((provider.readByte(index++) & 0xff) << 8);
    +            buffer.append(c);
    +        }
    +        return buffer.toString().trim();
    +    }
    +
    +    /**
    +     * Returns the BYTE at <code>index<code>.
    +     * @param index the index where the BYTE begins
    +     * @return the BYTE
    +     * @exception IOException if an I/O error occurs
    +     */
    +    public byte readByte(long index) throws IOException {
    +        return provider.readByte(index);
    +    }
    +
    +    /**
    +     * Returns the BYTE at <code>index</code>.
    +     * @param index the index where the BYTE begins
    +     * @return the BYTE
    +     * @exception IOException if an I/O error occurs
    +     */
    +    public byte readByte(long index, byte minClamp, byte maxClamp, Byte... exceptions) throws IOException {
    +        byte b = readByte(index);
    +        return clampByte(b, minClamp, maxClamp, exceptions);
    +    }
    +
    +    /**
    +     * Returns the SHORT at <code>index</code>.
    +     * @param index the index where the SHORT begins
    +     * @return the SHORT
    +     * @exception IOException if an I/O error occurs
    +     */
    +    public short readShort(long index) throws IOException {
    +        byte [] bytes = provider.readBytes(index, SIZEOF_SHORT);
    +        return converter.getShort(bytes);
    +    }
    +
    +    /**
    +     * Returns the SHORT at <code>index</code>.
    +     * @param index the index where the SHORT begins
    +     * @return the SHORT
    +     * @exception IOException if an I/O error occurs
    +     */
    +    public short readShort(long index, short minClamp, short maxClamp, Short... exceptions) throws IOException {
    +        short s = readShort(index);
    +        return clampShort(s, minClamp, maxClamp, exceptions);
    +    }
    +
    +    /**
    +     * Returns the INTEGER at <code>index</code>.
    +     * @param index the index where the INTEGER begins
    +     * @return the INTEGER
    +     * @exception IOException if an I/O error occurs
    +     */
    +    public int readInt(long index) throws IOException {
    +        byte [] bytes = provider.readBytes(index, SIZEOF_INT);
    +        return converter.getInt(bytes);
    +    }
    +
    +    /**
    +     * Returns the INTEGER at <code>index</code>.
    +     * @param index the index where the INTEGER begins
    +     * @return the INTEGER
    +     * @exception IOException if an I/O error occurs
    +     */
    +    public int readInt(long index, int minClamp, int maxClamp, Integer... exceptions) throws IOException {
    +        int i = readInt(index);
    +        return clampInt(i, minClamp, maxClamp, exceptions);
    +    }
    +
    +    /**
    +     * Returns the LONG at <code>index</code>.
    +     * @param index the index where the LONG begins
    +     * @return the LONG
    +     * @exception IOException if an I/O error occurs
    +     */
    +    public long readLong(long index) throws IOException {
    +        byte [] bytes = provider.readBytes(index, SIZEOF_LONG);
    +        return converter.getLong(bytes);
    +    }
    +
    +    /**
    +     * Returns the LONG at <code>index</code>.
    +     * @param index the index where the LONG begins
    +     * @return the LONG
    +     * @exception IOException if an I/O error occurs
    +     */
    +    public long readLong(long index, long minClamp, long maxClamp, Long... exceptions) throws IOException {
    +        long l = readLong(index);
    +        return clampLong(l, minClamp, maxClamp, exceptions);
    +    }
    +
    +    /**
    +     * Returns the BYTE array of <code>nElements</code>
    +     * starting at <code>index</code>.
    +     * @param index the index where the BYTE begins
    +     * @param nElements the number of array elements
    +     * @return the BYTE array
    +     * @exception IOException if an I/O error occurs
    +     */
    +    public byte [] readByteArray(long index, int nElements) throws IOException {
    +        if (nElements < 0) {
    +            throw new IOException("Invalid number of elements specified: "+nElements);
    +        }
    +        return provider.readBytes(index, nElements);
    +    }
    +
    +    /**
    +     * Returns the BYTE array of <code>nElements</code>
    +     * starting at <code>index</code>.
    +     * @param index the index where the BYTE begins
    +     * @param nElements the number of array elements
    +     * @return the BYTE array
    +     * @exception IOException if an I/O error occurs
    +     */
    +    public byte [] readByteArray(long index, int nElements, byte minClamp, byte maxClamp, Byte... exceptions) throws IOException {
    +        byte[] array = readByteArray(index, nElements);
    +        for (int ii = 0; ii < array.length; ++ii) {
    +            array[ii] = clampByte(array[ii], minClamp, maxClamp, exceptions);
    +        }
    +        return array;
    +    }
    +
    +    /**
    +     * Returns the SHORT array of <code>nElements</code>
    +     * starting at <code>index</code>.
    +     * @param index the index where the SHORT begins
    +     * @param nElements the number of array elements
    +     * @return the SHORT array
    +     * @exception IOException if an I/O error occurs
    +     */
    +    public short [] readShortArray(long index, int nElements) throws IOException {
    +        if (nElements < 0) {
    +            throw new IOException("Invalid number of elements specified: "+nElements);
    +        }
    +        short [] arr = new short[nElements];
    +        for (int i = 0 ; i < nElements ; ++i) {
    +            arr[i] = readShort(index);
    +            index += SIZEOF_SHORT;
    +        }
    +        return arr;
    +    }
    +
    +    /**
    +     * Returns the SHORT array of <code>nElements</code>
    +     * starting at <code>index</code>.
    +     * @param index the index where the SHORT begins
    +     * @param nElements the number of array elements
    +     * @return the SHORT array
    +     * @exception IOException if an I/O error occurs
    +     */
    +    public short [] readShortArray(long index, int nElements, short minClamp, short maxClamp, Short... exceptions) throws IOException {
    +        short[] array = readShortArray(index, nElements);
    +        for (int ii = 0; ii < array.length; ++ii) {
    +            array[ii] = clampShort(array[ii], minClamp, maxClamp, exceptions);
    +        }
    +        return array;
    +    }
    +
    +    /**
    +     * Returns the INTEGER array of <code>nElements</code>
    +     * starting at <code>index</code>.
    +     * @param index the index where the INTEGER begins
    +     * @param nElements the number of array elements
    +     * @return the INTEGER array
    +     * @exception IOException if an I/O error occurs
    +     */
    +    public int [] readIntArray(long index, int nElements) throws IOException {
    +        if (nElements < 0) {
    +            throw new IOException("Invalid number of elements specified: "+nElements);
    +        }
    +        int [] arr = new int[nElements];
    +        for (int i = 0 ; i < nElements ; ++i) {
    +            arr[i] = readInt(index);
    +            index += SIZEOF_INT;
    +        }
    +        return arr;
    +    }
    +
    +    /**
    +     * Returns the INTEGER array of <code>nElements</code>
    +     * starting at <code>index</code>.
    +     * @param index the index where the INTEGER begins
    +     * @param nElements the number of array elements
    +     * @return the INTEGER array
    +     * @exception IOException if an I/O error occurs
    +     */
    +    public int [] readIntArray(long index, int nElements, int minClamp, int maxClamp, Integer... exceptions) throws IOException {
    +        int[] array = readIntArray(index, nElements);
    +        for (int ii = 0; ii < array.length; ++ii) {
    +            array[ii] = clampInt(array[ii], minClamp, maxClamp, exceptions);
    +        }
    +        return array;
    +    }
    +
    +    /**
    +     * Returns the LONG array of <code>nElements</code>
    +     * starting at <code>index</code>.
    +     * @param index the index where the LONG begins
    +     * @param nElements the number of array elements
    +     * @return the LONG array
    +     * @exception IOException if an I/O error occurs
    +     */
    +    public long [] readLongArray(long index, int nElements) throws IOException {
    +        if (nElements < 0) {
    +            throw new IOException("Invalid number of elements specified: "+nElements);
    +        }
    +        long [] arr = new long[nElements];
    +        for (int i = 0 ; i < nElements ; ++i) {
    +            arr[i] = readLong(index);
    +            index += SIZEOF_LONG;
    +        }
    +        return arr;
    +    }
    +
    +    /**
    +     * Returns the LONG array of <code>nElements</code>
    +     * starting at <code>index</code>.
    +     * @param index the index where the LONG begins
    +     * @param nElements the number of array elements
    +     * @return the LONG array
    +     * @exception IOException if an I/O error occurs
    +     */
    +    public long [] readLongArray(long index, int nElements, long minClamp, long maxClamp, Long... exceptions) throws IOException {
    +        long[] array = readLongArray(index, nElements);
    +        for (int ii = 0; ii < array.length; ++ii) {
    +            array[ii] = clampLong(array[ii], minClamp, maxClamp, exceptions);
    +        }
    +        return array;
    +    }
    +
    +    /**
    +     * Returns the Ascii string array of <code>nElements</code>
    +     * starting at <code>index</code>
    +     * @param index the index where the Ascii Strings begin
    +     * @param nElements the number of array elements
    +     * @return the Ascii String array
    +     * @exception IOException if an I/O error occurs
    +     */
    +    public String [] readAsciiStringArray(long index, int nElements) throws IOException {
    +        if (nElements < 0) {
    +            throw new IOException("Invalid number of elements specified: "+nElements);
    +        }
    +        String [] arr = new String[nElements];
    +        for (int i = 0 ; i < nElements ; ++i) {
    +            String tmp = readAsciiString(index);
    +            arr[i] = tmp;
    +            index += (tmp == null ? 1 : tmp.length());
    +        }
    +        return arr;
    +    }
    +
    +    /**
    +     * Writes the specified byte at the specified index.
    +     * @param index the index where the byte should be written
    +     * @param value the byte value to be written
    +     * @exception IOException if an I/O error occurs
    +     */
    +    public void writeByte(long index, byte value) throws IOException {
    +        provider.writeByte(index, value);
    +    }
    +
    +    /**
    +     * Writes the specified short at the specified index.
    +     * @param index the index where the short should be written
    +     * @param value the short value to be written
    +     * @exception IOException if an I/O error occurs
    +     */
    +    public void writeShort(long index, short value) throws IOException {
    +        byte [] bytes = converter.getBytes(value);
    +        provider.writeBytes(index, bytes);
    +    }
    +
    +    /**
    +     * Writes the specified int at the specified index.
    +     * @param index the index where the int should be written
    +     * @param value the int value to be written
    +     * @exception IOException if an I/O error occurs
    +     */
    +    public void writeInt(long index, int value) throws IOException {
    +        byte [] bytes = converter.getBytes(value);
    +        provider.writeBytes(index, bytes);
    +    }
    +
    +    /**
    +     * Writes the specified long at the specified index.
    +     * @param index the index where the long should be written
    +     * @param value the long value to be written
    +     * @exception IOException if an I/O error occurs
    +     */
    +    public void writeLong(long index, long value) throws IOException {
    +        byte [] bytes = converter.getBytes(value);
    +        provider.writeBytes(index, bytes);
    +    }
    +
    +    /**
    +     * Returns the underlying byte provider.
    +     * @return the underlying byte provider
    +     */
    +    public GByteProvider getByteProvider() {
    +        return provider;
    +    }
    +
    +    protected byte clampByte(byte b, byte minClamp, byte maxClamp, Byte... exceptions) {
    +        if (maxClamp < minClamp) {
    +            throw new IllegalArgumentException("maxClamp < minClamp not allowed");
    +        }
    +        if (exceptions != null) {
    +            if (exceptions.length % 2 != 0) {
    +                throw new IllegalArgumentException("exceptions must be pairs of (flag, replacement) bytes");
    +            }
    +        }
    +        boolean clamp = true;
    +        if (exceptions != null) {
    +            for (int ii = 0; ii < exceptions.length; ii += 2) {
    +                if (b == exceptions[ii]) {
    +                    b = exceptions[ii+1];
    +                    clamp = false;
    +                    break;
    +                }
    +            }
    +        }
    +        if (clamp) {
    +            if (b < minClamp) {
    +                b = minClamp;
    +            } else if (b > maxClamp) {
    +                b = maxClamp;
    +            }
    +        }
    +        return b;
    +    }
    +
    +    protected short clampShort(short s, short minClamp, short maxClamp, Short... exceptions) {
    +        if (maxClamp < minClamp) {
    +            throw new IllegalArgumentException("maxClamp < minClamp not allowed");
    +        }
    +        if (exceptions != null) {
    +            if (exceptions.length % 2 != 0) {
    +                throw new IllegalArgumentException("exceptions must be pairs of (flag, replacement) shorts");
    +            }
    +        }
    +        boolean clamp = true;
    +        if (exceptions != null) {
    +            for (int ii = 0; ii < exceptions.length; ii += 2) {
    +                if (s == exceptions[ii]) {
    +                    s = exceptions[ii+1];
    +                    clamp = false;
    +                    break;
    +                }
    +            }
    +        }
    +        if (clamp) {
    +            if (s < minClamp) {
    +                s = minClamp;
    +            } else if (s > maxClamp) {
    +                s = maxClamp;
    +            }
    +        }
    +        return s;
    +    }
    +
    +    protected int clampInt(int i, int minClamp, int maxClamp, Integer... exceptions) {
    +        if (maxClamp < minClamp) {
    +            throw new IllegalArgumentException("maxClamp < minClamp not allowed");
    +        }
    +        if (exceptions != null) {
    +            if (exceptions.length % 2 != 0) {
    +                throw new IllegalArgumentException("exceptions must be pairs of (flag, replacement) ints");
    +            }
    +        }
    +        boolean clamp = true;
    +        if (exceptions != null) {
    +            for (int ii = 0; ii < exceptions.length; ii += 2) {
    +                if (i == exceptions[ii]) {
    +                    i = exceptions[ii+1];
    +                    clamp = false;
    +                    break;
    +                }
    +            }
    +        }
    +        if (clamp) {
    +            if (i < minClamp) {
    +                i = minClamp;
    +            } else if (i > maxClamp) {
    +                i = maxClamp;
    +            }
    +        }
    +        return i;
    +    }
    +
    +    protected long clampLong(long l, long minClamp, long maxClamp, Long... exceptions) {
    +        if (maxClamp < minClamp) {
    +            throw new IllegalArgumentException("maxClamp < minClamp not allowed");
    +        }
    +        if (exceptions != null) {
    +            if (exceptions.length % 2 != 0) {
    +                throw new IllegalArgumentException("exceptions must be pairs of (flag, replacement) longs");
    +            }
    +        }
    +        boolean clamp = true;
    +        if (exceptions != null) {
    +            for (int ii = 0; ii < exceptions.length; ii += 2) {
    +                if (l == exceptions[ii]) {
    +                    l = exceptions[ii+1];
    +                    clamp = false;
    +                    break;
    +                }
    +            }
    +        }
    +        if (clamp) {
    +            if (l < minClamp) {
    +                l = minClamp;
    +            } else if (l > maxClamp) {
    +                l = maxClamp;
    +            }
    +        }
    +        return l;
    +    }
    +}
    
  • GPL/DMG/src/dmg/java/mobiledevices/dmg/ghidra/GByteProvider.java+126 0 added
    @@ -0,0 +1,126 @@
    +/* ###
    + * IP: Public Domain
    + */
    +package mobiledevices.dmg.ghidra;
    +
    +
    +import java.io.*;
    +
    +/**
    + * An implementation of ByteProvider where the underlying
    + * bytes are supplied by a random access file.
    + */
    +public class GByteProvider implements Closeable {
    +    private File file;
    +    private GRandomAccessFile randomAccessFile;
    +
    +    /**
    +     * Constructs a byte provider using the specified file
    +     * @param file the file to open for random access
    +     * @throws FileNotFoundException if the file does not exist
    +     */
    +    public GByteProvider(File file) throws IOException {
    +        this.file = file;
    +        this.randomAccessFile = new GRandomAccessFile(file, "r");
    +    }
    +
    +    /**
    +     * Constructs a byte provider using the specified file and permissions string
    +     * @param file the file to open for random access
    +     * @param string indicating permissions used for open
    +     * @throws FileNotFoundException if the file does not exist
    +     */
    +    public GByteProvider(File file, String permissions) throws IOException {
    +        this.file = file;
    +        this.randomAccessFile = new GRandomAccessFile(file, permissions);
    +    }
    +
    +    /**
    +     * @see GByteProvider.app.util.bin.ByteProvider#getFile()
    +     */
    +    public File getFile() {
    +		return file;
    +	}
    +
    +    /**
    +     * @see GByteProvider.app.util.bin.ByteProvider#getName()
    +     */
    +    public String getName() {
    +        return file.getName();
    +    }
    +
    +    public String getAbsolutePath() {
    +        return file.getAbsolutePath();
    +    }
    +
    +    /**
    +     * @see GByteProvider.app.util.bin.ByteProvider#getInputStream(long)
    +     */
    +    public InputStream getInputStream(long index) throws IOException {
    +        FileInputStream is = new FileInputStream(file);
    +        is.skip(index);
    +        return is;
    +    }
    +
    +    /**
    +     * Closes the underlying random-access file.
    +     * @throws IOException if an I/O error occurs
    +     */
    +	@Override
    +    public void close() throws IOException {
    +        randomAccessFile.close();
    +    }
    +
    +    /**
    +     * @see GByteProvider.app.util.bin.ByteProvider#length()
    +     */
    +    public long length() throws IOException {
    +        return randomAccessFile.length();
    +    }
    +
    +    public boolean isValidIndex(long index) {
    +    	try {
    +    		return index >= 0 && index < randomAccessFile.length();
    +    	}
    +    	catch (IOException e) {
    +    	}
    +    	return false;
    +    }
    +
    +    /**
    +     * @see GByteProvider.app.util.bin.ByteProvider#readByte(long)
    +     */
    +    public byte readByte(long index) throws IOException {
    +        randomAccessFile.seek(index);
    +        return randomAccessFile.readByte();
    +    }
    +
    +    /**
    +     * @see GByteProvider.app.util.bin.ByteProvider#readBytes(long, long)
    +     */
    +    public byte [] readBytes(long index, long length) throws IOException {
    +        randomAccessFile.seek(index);
    +        byte [] b = new byte[(int)length];
    +        int nRead = randomAccessFile.read(b);
    +        if (nRead != length) {
    +            throw new IOException("Unable to read "+length+" bytes");
    +        }
    +        return b;
    +    }
    +
    +    /**
    +     * @see GByteProvider.app.util.bin.ByteProvider#writeByte(long, byte)
    +     */
    +    public void writeByte(long index, byte value) throws IOException {
    +        randomAccessFile.seek(index);
    +        randomAccessFile.write(value);
    +    }
    +
    +    /**
    +     * @see GByteProvider.app.util.bin.ByteProvider#writeBytes(long, byte[])
    +     */
    +    public void writeBytes(long index, byte [] values) throws IOException {
    +        randomAccessFile.seek(index);
    +        randomAccessFile.write(values);
    +    }
    +}
    
  • GPL/DMG/src/dmg/java/mobiledevices/dmg/ghidra/GConv.java+136 0 added
    @@ -0,0 +1,136 @@
    +/* ###
    + * IP: Public Domain
    + */
    +package mobiledevices.dmg.ghidra;
    +
    +/**
    + * Helper methods for converting between
    + * number data types without negative
    + * promotion.
    + * 
    + * 
    + */ 
    +public class GConv {
    +	
    +	private GConv() {
    +	}
    +	
    +    /**
    +     * A byte mask.
    +     */
    +    public static final int BYTE_MASK = 0xff;
    +    /**
    +     * A short mask.
    +     */
    +    public static final int SHORT_MASK = 0xffff;
    +    /**
    +     * An integer mask.
    +     */
    +    public static final long INT_MASK = 0x00000000ffffffffL;
    +    /**
    +     * Converts a byte to a short.
    +     * @param b the byte
    +     * @return the short equivalent of the byte
    +     */
    +    public static short byteToShort(byte b) {
    +        return (short)(b & BYTE_MASK);
    +    }
    +    /**
    +     * Converts a byte to an integer.
    +     * @param b the byte
    +     * @return the integer equivalent of the byte
    +     */
    +    public static int byteToInt(byte b) {
    +        return (b & BYTE_MASK);
    +    }
    +    /**
    +     * Converts a byte to a long.
    +     * @param b the byte
    +     * @return the long equivalent of the byte
    +     */
    +    public static long byteToLong(byte b) {
    +        return intToLong(b & BYTE_MASK);
    +    }
    +    /**
    +     * Converts a short to an integer.
    +     * @param s the short
    +     * @return the integer equivalent of the short
    +     */
    +    public static int shortToInt(short s) {
    +        return (s & SHORT_MASK);
    +    }
    +    /**
    +     * Converts a short to a long.
    +     * @param s the short
    +     * @return the long eqivalent of the short
    +     */
    +    public static long shortToLong(short s) {
    +        return intToLong(s & SHORT_MASK);
    +    }
    +    /**
    +     * Converts an integer to a long.
    +     * @param i the integer
    +     * @return the long equivalent of the long
    +     */
    +    public static long intToLong(int i) {
    +        return (i & INT_MASK);
    +    }
    +
    +    public static String toString(byte [] array) {
    +    	StringBuffer buffer = new StringBuffer();
    +    	for (byte b : array) {
    +			buffer.append((char)b);
    +		}
    +    	return buffer.toString();
    +    }
    +    /**
    +     * Converts a byte into a padded hex string.
    +     * @param b the byte
    +     * @return the padded hex string
    +     */
    +    public static String toHexString(byte b) {
    +        return zeropad(Integer.toHexString(byteToInt(b)), 2);
    +    }
    +    /**
    +     * Converts a short into a padded hex string.
    +     * @param s the short
    +     * @return the padded hex string
    +     */
    +    public static String toHexString(short s) {
    +        return zeropad(Integer.toHexString(shortToInt(s)), 4);
    +    }
    +    /**
    +     * Converts an integer into a padded hex string.
    +     * @param i the integer
    +     * @return the padded hex string
    +     */
    +    public static String toHexString(int i) {
    +        return zeropad(Integer.toHexString(i), 8);
    +    }
    +    /**
    +     * Converts a long into a padded hex string.
    +     * @param l the long
    +     * @return the padded hex string
    +     */
    +    public static String toHexString(long l) {
    +        return zeropad(Long.toHexString(l), 16);
    +    }
    +
    +    /**
    +     * Returns a string that is extended to 
    +     * length len with zeroes.
    +     * @param s The string to pad
    +     * @param len The length of the return string
    +     * @return A string that has been padded to be of legnth len
    +     */
    +    public static String zeropad(String s, int len) {
    +        if (s == null) s = "";
    +        StringBuffer buffer = new StringBuffer(s);
    +        int zerosNeeded = len - s.length();
    +        for (int i = 0 ; i < zerosNeeded ; ++i) {
    +            buffer.insert(0, '0');
    +        }
    +        return buffer.toString();
    +    }
    +
    +}
    
  • GPL/DMG/src/dmg/java/mobiledevices/dmg/ghidra/GDataConverterBE.java+224 0 added
    @@ -0,0 +1,224 @@
    +/* ###
    + * IP: Public Domain
    + */
    +package mobiledevices.dmg.ghidra;
    +
    +/**
    + * Helper class to convert a byte array to Java primitives and primitives to a
    + * byte array in Big endian.
    + * 
    + * 
    + * 
    + */
    +public class GDataConverterBE implements GDataConverter {
    +	public static final GDataConverterBE INSTANCE = new GDataConverterBE();
    +
    +	/**
    +	 * 
    +	 */
    +	private static final long serialVersionUID = 1L;
    +
    +	/**
    +	 * Constructor for BigEndianDataConverter.
    +	 */
    +	public GDataConverterBE() {
    +	}
    +
    +	/**
    +	 * @see GDataConverter#getShort(byte[])
    +	 */
    +	public final short getShort(byte[] b) {
    +		return getShort(b, 0);
    +	}
    +
    +	/**
    +	 * @see GDataConverter#getShort(byte[], int)
    +	 */
    +	public short getShort(byte[] b, int offset) {
    +		return (short) (((b[offset] & 0xff) << 8) | (b[offset + 1] & 0xff));
    +	}
    +
    +	/**
    +	 * @see GDataConverter#getInt(byte[])
    +	 */
    +	public final int getInt(byte[] b) {
    +		return getInt(b, 0);
    +	}
    +
    +	/**
    +	 * @see GDataConverter#getInt(byte[], int)
    +	 */
    +	public int getInt(byte[] b, int offset) {
    +		int v = b[offset];
    +		for (int i = 1; i < 4; i++) {
    +			v = (v << 8) | (b[offset + i] & 0xff);
    +		}
    +		return v;
    +	}
    +
    +	/**
    +	 * @see GDataConverter#getLong(byte[])
    +	 */
    +	public final long getLong(byte[] b) {
    +		return getLong(b, 0);
    +	}
    +
    +	/**
    +	 * @see GDataConverter#getLong(byte[], int)
    +	 */
    +	public long getLong(byte[] b, int offset) {
    +		long v = b[offset];
    +		for (int i = 1; i < 8; i++) {
    +			v = (v << 8) | (b[offset + i] & 0xff);
    +		}
    +		return v;
    +	}
    +
    +	/**
    +	 * @see GDataConverter.util.DataConverter#getValue(byte[], int)
    +	 */
    +	public long getValue(byte[] b, int size) {
    +		return getValue(b, 0, size);
    +	}
    +
    +	/**
    +	 * @see GDataConverter.util.DataConverter#getValue(byte[], int, int)
    +	 */
    +	public long getValue(byte[] b, int offset, int size) {
    +		if (size > 8) {
    +			throw new IndexOutOfBoundsException("size exceeds sizeof long: " + size);
    +		}
    +		long val = 0;
    +		for (int i = 0; i < size; i++) {
    +			val = (val << 8) | (b[offset + i] & 0xff);
    +		}
    +		return val;
    +	}
    +
    +	/**
    +	 * @see GDataConverter#getBytes(short, byte[])
    +	 */
    +	public final void getBytes(short value, byte[] b) {
    +		getBytes(value, b, 0);
    +	}
    +
    +	/**
    +	 * @see GDataConverter#getBytes(short, byte[], int)
    +	 */
    +	public void getBytes(short value, byte[] b, int offset) {
    +		b[offset] = (byte) (value >> 8);
    +		b[offset + 1] = (byte) (value & 0xff);
    +	}
    +
    +	/**
    +	 * @see GDataConverter#getBytes(int, byte[])
    +	 */
    +	public final void getBytes(int value, byte[] b) {
    +		getBytes(value, b, 0);
    +	}
    +
    +	/**
    +	 * @see GDataConverter#getBytes(int, byte[], int)
    +	 */
    +	public void getBytes(int value, byte[] b, int offset) {
    +		b[offset + 3] = (byte) (value);
    +		for (int i = 2; i >= 0; i--) {
    +			value >>= 8;
    +			b[offset + i] = (byte) (value);
    +		}
    +	}
    +
    +	/**
    +	 * @see GDataConverter#getBytes(long, byte[])
    +	 */
    +	public final void getBytes(long value, byte[] b) {
    +		getBytes(value, 8, b, 0);
    +	}
    +
    +	/**
    +	 * @see GDataConverter#getBytes(long, byte[], int)
    +	 */
    +	public void getBytes(long value, byte[] b, int offset) {
    +		getBytes(value, 8, b, offset);
    +	}
    +
    +	/**
    +	 * @see GDataConverter.util.DataConverter#getBytes(long, int, byte[], int)
    +	 */
    +	public void getBytes(long value, int size, byte[] b, int offset) {
    +		for (int i = size - 1; i >= 0; i--) {
    +			b[offset + i] = (byte) value;
    +			value >>= 8;
    +		}
    +	}
    +
    +	/**
    +	 * @see GDataConverter.util.DataConverter#putInt(byte[], int, int)
    +	 */
    +	public final void putInt(byte[] b, int offset, int value) {
    +		getBytes(value, b, offset);
    +	}
    +
    +	/**
    +	 * @see GDataConverter.util.DataConverter#putInt(byte[], int)
    +	 */
    +	public final void putInt(byte[] b, int value) {
    +		getBytes(value, b);
    +	}
    +
    +	/**
    +	 * @see GDataConverter.util.DataConverter#putLong(byte[], int, long)
    +	 */
    +	public final void putLong(byte[] b, int offset, long value) {
    +		getBytes(value, b, offset);
    +	}
    +
    +	/**
    +	 * @see GDataConverter.util.DataConverter#putLong(byte[], long)
    +	 */
    +	public final void putLong(byte[] b, long value) {
    +		getBytes(value, b);
    +	}
    +
    +	/**
    +	 * @see GDataConverter.util.DataConverter#putShort(byte[], int, short)
    +	 */
    +	public final void putShort(byte[] b, int offset, short value) {
    +		getBytes(value, b, offset);
    +	}
    +
    +	/**
    +	 * @see GDataConverter.util.DataConverter#putShort(byte[], short)
    +	 */
    +	public final void putShort(byte[] b, short value) {
    +		getBytes(value, b);
    +	}
    +
    +	/**
    +	 * @see GDataConverter.util.DataConverter#getBytes(int)
    +	 */
    +	public byte[] getBytes(int value) {
    +		byte[] bytes = new byte[4];
    +		getBytes(value, bytes);
    +		return bytes;
    +	}
    +
    +	/**
    +	 * @see GDataConverter.util.DataConverter#getBytes(long)
    +	 */
    +	public byte[] getBytes(long value) {
    +		byte[] bytes = new byte[8];
    +		getBytes(value, bytes);
    +		return bytes;
    +	}
    +
    +	/**
    +	 * @see GDataConverter.util.DataConverter#getBytes(short)
    +	 */
    +	public byte[] getBytes(short value) {
    +		byte[] bytes = new byte[2];
    +		getBytes(value, bytes);
    +		return bytes;
    +	}
    +
    +}
    
  • GPL/DMG/src/dmg/java/mobiledevices/dmg/ghidra/GDataConverter.java+218 0 added
    @@ -0,0 +1,218 @@
    +/* ###
    + * IP: Public Domain
    + */
    +package mobiledevices.dmg.ghidra;
    +
    +import java.io.Serializable;
    +
    +/**
    + * 
    + * Defines methods to convert byte arrays to a specific primitive Java types,
    + * and to populate byte arrays from primitive Java types.
    + * 
    + * 
    + */
    +public interface GDataConverter extends Serializable {
    +
    +	/**
    +	 * Get the short value from the given byte array.
    +	 * @param b array containing bytes
    +	 * @throws IndexOutOfBoundsException if byte array size is
    +	 * less than 2.
    +	 */
    +	public short getShort(byte[] b);
    +
    +	/**
    +	 * Get the short value from the given byte array.
    +	 * @param b array containing bytes
    +	 * @param offset offset into byte array for getting the short
    +	 * @throws IndexOutOfBoundsException if byte array size is
    +	 * less than offset+2.
    +	 */
    +	public short getShort(byte[] b, int offset);
    +
    +	/**
    +	 * Get the int value from the given byte array.
    +	 * @param b array containing bytes
    +	 * @throws IndexOutOfBoundsException if byte array size is
    +	 * less than 4.
    +	 */
    +	public int getInt(byte[] b);
    +
    +	/**
    +	 * Get the int value from the given byte array.
    +	 * @param b array containing bytes
    +	 * @param offset offset into byte array for getting the int
    +	 * @throws IndexOutOfBoundsException if byte array size is
    +	 * less than offset+4.
    +	 */
    +	public int getInt(byte[] b, int offset);
    +
    +	/**
    +	 * Get the long value from the given byte array.
    +	 * @param b array containing bytes
    +	 * @throws IndexOutOfBoundsException if byte array size is
    +	 * less than 8.
    +	 */
    +	public long getLong(byte[] b);
    +
    +	/**
    +	 * Get the long value from the given byte array.
    +	 * @param b array containing bytes
    +	 * @param offset offset into byte array for getting the long
    +	 * @throws IndexOutOfBoundsException if byte array size is
    +	 * less than offset+8.
    +	 */
    +	public long getLong(byte[] b, int offset);
    +
    +	/**
    +	 * Get the value from the given byte array using the specified size.
    +	 * @param b array containing bytes
    +	 * @param size number of bytes to use from array at offset 0
    +	 * @throws IndexOutOfBoundsException if byte array size is
    +	 * less than size.
    +	 */
    +	public long getValue(byte[] b, int size);
    +
    +	/**
    +	 * Get the value from the given byte array using the specified size.
    +	 * @param b array containing bytes
    +	 * @param size number of bytes to use from array
    +	 * @param offset offset into byte array for getting the long
    +	 * @throws IndexOutOfBoundsException if byte array size is
    +	 * less than offset+size or size is greater than 8 (sizeof long).
    +	 */
    +	public long getValue(byte[] b, int offset, int size);
    +
    +	/**
    +	 * Converts the given value to bytes.
    +	 * @param value value to convert to bytes
    +	 * @param b byte array to store bytes
    +	 * @throws IndexOutOfBoundsException if b.length is not at least
    +	 * 2.
    +	 */
    +	public void getBytes(short value, byte[] b);
    +
    +	/**
    +	 * Converts the given value to bytes.
    +	 * @param value value to convert to bytes
    +	 * @param b byte array to store bytes
    +	 * @param offset offset into byte array to put the bytes
    +	 * @throws IndexOutOfBoundsException if (offset+2)>b.length
    +	 */
    +	public void getBytes(short value, byte[] b, int offset);
    +
    +	/**
    +	 * Converts the given value to bytes.
    +	 * @param value value to convert to bytes
    +	 * @param b byte array to store bytes
    +	 * @throws IndexOutOfBoundsException if b.length is not at least
    +	 * 4.
    +	 */
    +	public void getBytes(int value, byte[] b);
    +
    +	/**
    +	 * Converts the given value to bytes.
    +	 * @param value value to convert to bytes
    +	 * @param b byte array to store bytes
    +	 * @param offset offset into byte array to put the bytes
    +	 * @throws IndexOutOfBoundsException if (offset+4)>b.length
    +	 */
    +	public void getBytes(int value, byte[] b, int offset);
    +
    +	/**
    +	 * Converts the given value to bytes.
    +	 * @param value value to convert to bytes
    +	 * @param b byte array to store bytes
    +	 * @throws IndexOutOfBoundsException if b.length is not at least
    +	 * 8.
    +	 */
    +	public void getBytes(long value, byte[] b);
    +
    +	/**
    +	 * Converts the given value to bytes.
    +	 * @param value value to convert to bytes
    +	 * @param b byte array to store bytes
    +	 * @param offset offset into byte array to put the bytes
    +	 * @throws IndexOutOfBoundsException if (offset+8)>b.length
    +	 */
    +	public void getBytes(long value, byte[] b, int offset);
    +
    +	/**
    +	 * Converts the given value to bytes using the number of least significant bytes
    +	 * specified by size.
    +	 * @param value value to convert to bytes
    +	 * @param size number of least significant bytes of value to be written to the byte array
    +	 * @param b byte array to store bytes
    +	 * @param offset offset into byte array to put the bytes
    +	 * @throws IndexOutOfBoundsException if (offset+size)>b.length.
    +	 */
    +	public void getBytes(long value, int size, byte[] b, int offset);
    +
    +	/**
    +	 * Converts the short value to an array of bytes.
    +	 * @param value short value to be converted
    +	 * @return array of bytes
    +	 */
    +	public byte[] getBytes(short value);
    +
    +	/**
    +	 * Converts the int value to an array of bytes.
    +	 * @param value int value to be converted
    +	 * @return array of bytes
    +	 */
    +	public byte[] getBytes(int value);
    +
    +	/**
    +	 * Converts the long value to an array of bytes.
    +	 * @param value long value to be converted
    +	 * @return array of bytes
    +	 */
    +	public byte[] getBytes(long value);
    +
    +	/**
    +	 * Writes a short value into a byte array.
    +	 * @param b array to contain the bytes;
    +	 * @param value the short value
    +	 */
    +	public void putShort(byte[] b, short value);
    +
    +	/**
    +	 * Writes a short value into the byte array at the given offset
    +	 * @param b array to contain the bytes;
    +	 * @param offset the offset into the byte array to store the value.
    +	 * @param value the short value
    +	 */
    +	public void putShort(byte[] b, int offset, short value);
    +
    +	/**
    +	 * Writes a int value into a byte array.
    +	 * @param b array to contain the bytes;
    +	 * @param value the int value
    +	 */
    +	public void putInt(byte[] b, int value);
    +
    +	/**
    +	 * Writes a int value into the byte array at the given offset
    +	 * @param b array to contain the bytes;
    +	 * @param offset the offset into the byte array to store the value.
    +	 * @param value the int value
    +	 */
    +	public void putInt(byte[] b, int offset, int value);
    +
    +	/**
    +	 * Writes a long value into a byte array.
    +	 * @param b array to contain the bytes;
    +	 * @param value the long value
    +	 */
    +	public void putLong(byte[] b, long value);
    +
    +	/**
    +	 * Writes a long value into the byte array at the given offset
    +	 * @param b array to contain the bytes;
    +	 * @param offset the offset into the byte array to store the value.
    +	 * @param value the long value
    +	 */
    +	public void putLong(byte[] b, int offset, long value);
    +
    +}
    
  • GPL/DMG/src/dmg/java/mobiledevices/dmg/ghidra/GDataConverterLE.java+222 0 added
    @@ -0,0 +1,222 @@
    +/* ###
    + * IP: Public Domain
    + */
    +package mobiledevices.dmg.ghidra;
    +
    +/**
    + * 
    + * Helper class to convert a byte array to a Java primitive in Little endian
    + * order, and to convert a primitive to a byte array.
    + */
    +
    +public class GDataConverterLE implements GDataConverter {
    +	public static GDataConverterLE INSTANCE = new GDataConverterLE();
    +	/**
    +	 * 
    +	 */
    +	private static final long serialVersionUID = 1L;
    +
    +	/**
    +	 * Constructor for BigEndianDataConverter.
    +	 */
    +	public GDataConverterLE() {
    +	}
    +
    +	/**
    +	 * @see GDataConverter#getShort(byte[])
    +	 */
    +	public final short getShort(byte[] b) {
    +		return getShort(b, 0);
    +	}
    +
    +	/**
    +	 * @see GDataConverter#getShort(byte[], int)
    +	 */
    +	public short getShort(byte[] b, int offset) {
    +		return (short) (((b[offset + 1] & 0xff) << 8) | (b[offset] & 0xff));
    +	}
    +
    +	/**
    +	 * @see GDataConverter#getInt(byte[])
    +	 */
    +	public final int getInt(byte[] b) {
    +		return getInt(b, 0);
    +	}
    +
    +	/**
    +	 * @see GDataConverter#getInt(byte[], int)
    +	 */
    +	public int getInt(byte[] b, int offset) {
    +		int v = b[offset + 3];
    +		for (int i = 2; i >= 0; i--) {
    +			v = (v << 8) | (b[offset + i] & 0xff);
    +		}
    +		return v;
    +	}
    +
    +	/**
    +	 * @see GDataConverter#getLong(byte[])
    +	 */
    +	public final long getLong(byte[] b) {
    +		return getLong(b, 0);
    +	}
    +
    +	/**
    +	 * @see GDataConverter#getLong(byte[], int)
    +	 */
    +	public long getLong(byte[] b, int offset) {
    +		long v = b[offset + 7];
    +		for (int i = 6; i >= 0; i--) {
    +			v = (v << 8) | (b[offset + i] & 0xff);
    +		}
    +		return v;
    +	}
    +
    +	/**
    +	 * @see ghidra.util.GDataConverter#getValue(byte[], int)
    +	 */
    +	public long getValue(byte[] b, int size) {
    +		return getValue(b, 0, size);
    +	}
    +
    +	/**
    +	 * @see ghidra.util.GDataConverter#getValue(byte[], int, int)
    +	 */
    +	public long getValue(byte[] b, int offset, int size) {
    +		if (size > 8) {
    +			throw new IndexOutOfBoundsException("size exceeds sizeof long: " + size);
    +		}
    +		long val = 0;
    +		for (int i = size - 1; i >= 0; i--) {
    +			val = (val << 8) | (b[offset + i] & 0xff);
    +		}
    +		return val;
    +	}
    +
    +	/**
    +	 * @see GDataConverter#getBytes(short, byte[])
    +	 */
    +	public final void getBytes(short value, byte[] b) {
    +		getBytes(value, b, 0);
    +	}
    +
    +	/**
    +	 * @see GDataConverter#getBytes(short, byte[], int)
    +	 */
    +	public void getBytes(short value, byte[] b, int offset) {
    +		b[offset + 1] = (byte) (value >> 8);
    +		b[offset] = (byte) (value & 0xff);
    +	}
    +
    +	/**
    +	 * @see GDataConverter#getBytes(int, byte[])
    +	 */
    +	public final void getBytes(int value, byte[] b) {
    +		getBytes(value, b, 0);
    +	}
    +
    +	/**
    +	 * @see GDataConverter#getBytes(int, byte[], int)
    +	 */
    +	public void getBytes(int value, byte[] b, int offset) {
    +		b[offset] = (byte) (value);
    +		for (int i = 1; i < 4; i++) {
    +			value >>= 8;
    +			b[offset + i] = (byte) (value);
    +		}
    +	}
    +
    +	/**
    +	 * @see GDataConverter#getBytes(long, byte[])
    +	 */
    +	public final void getBytes(long value, byte[] b) {
    +		getBytes(value, 8, b, 0);
    +	}
    +
    +	/**
    +	 * @see GDataConverter#getBytes(long, byte[], int)
    +	 */
    +	public void getBytes(long value, byte[] b, int offset) {
    +		getBytes(value, 8, b, offset);
    +	}
    +
    +	/**
    +	 * @see ghidra.util.GDataConverter#getBytes(long, int, byte[], int)
    +	 */
    +	public void getBytes(long value, int size, byte[] b, int offset) {
    +		for (int i = 0; i < size; i++) {
    +			b[offset + i] = (byte) value;
    +			value >>= 8;
    +		}
    +	}
    +
    +	/**
    +	 * @see ghidra.util.GDataConverter#putInt(byte[], int, int)
    +	 */
    +	public final void putInt(byte[] b, int offset, int value) {
    +		getBytes(value, b, offset);
    +	}
    +
    +	/**
    +	 * @see ghidra.util.GDataConverter#putInt(byte[], int)
    +	 */
    +	public final void putInt(byte[] b, int value) {
    +		getBytes(value, b);
    +	}
    +
    +	/**
    +	 * @see ghidra.util.GDataConverter#putLong(byte[], int, long)
    +	 */
    +	public final void putLong(byte[] b, int offset, long value) {
    +		getBytes(value, b, offset);
    +	}
    +
    +	/**
    +	 * @see ghidra.util.GDataConverter#putLong(byte[], long)
    +	 */
    +	public final void putLong(byte[] b, long value) {
    +		getBytes(value, b);
    +	}
    +
    +	/**
    +	 * @see ghidra.util.GDataConverter#putShort(byte[], int, short)
    +	 */
    +	public final void putShort(byte[] b, int offset, short value) {
    +		getBytes(value, b, offset);
    +	}
    +
    +	/**
    +	 * @see ghidra.util.GDataConverter#putShort(byte[], short)
    +	 */
    +	public final void putShort(byte[] b, short value) {
    +		getBytes(value, b);
    +	}
    +
    +	/**
    +	 * @see ghidra.util.GDataConverter#getBytes(int)
    +	 */
    +	public byte[] getBytes(int value) {
    +		byte[] bytes = new byte[4];
    +		getBytes(value, bytes);
    +		return bytes;
    +	}
    +
    +	/**
    +	 * @see ghidra.util.GDataConverter#getBytes(long)
    +	 */
    +	public byte[] getBytes(long value) {
    +		byte[] bytes = new byte[8];
    +		getBytes(value, bytes);
    +		return bytes;
    +	}
    +
    +	/**
    +	 * @see ghidra.util.GDataConverter#getBytes(short)
    +	 */
    +	public byte[] getBytes(short value) {
    +		byte[] bytes = new byte[2];
    +		getBytes(value, bytes);
    +		return bytes;
    +	}
    +
    +}
    
  • GPL/DMG/src/dmg/java/mobiledevices/dmg/ghidra/GFileUtilityMethods.java+63 0 added
    @@ -0,0 +1,63 @@
    +/* ###
    + * IP: Public Domain
    + */
    +package mobiledevices.dmg.ghidra;
    +
    +import java.io.*;
    +
    +
    +public final class GFileUtilityMethods {
    +
    +	private static final String GHIDRA_FILE_SYSTEM_PREFIX = "ghidra_file_system_";
    +	private static final String GHIDRA_FILE_SYSTEM_SUFFIX = ".tmp";
    +
    +	public final static File writeTemporaryFile( InputStream inputStream ) throws IOException {
    +		return writeTemporaryFile( inputStream , Integer.MAX_VALUE );
    +	}
    +
    +	public final static File writeTemporaryFile( InputStream inputStream, int maxBytesToWrite ) throws IOException {
    +		File tempOutputFile = File.createTempFile( GHIDRA_FILE_SYSTEM_PREFIX, GHIDRA_FILE_SYSTEM_SUFFIX );
    +		tempOutputFile.deleteOnExit();
    +		OutputStream outputStream = new FileOutputStream( tempOutputFile );
    +		try {
    +			int nWritten = 0;
    +			byte [] buffer = new byte[ 8192 ];
    +			while ( true ) {
    +				int nRead = inputStream.read( buffer );
    +				if ( nRead == -1 ) {
    +					break;
    +				}
    +				outputStream.write( buffer, 0, nRead );
    +				nWritten += nRead;
    +				if ( nWritten >= maxBytesToWrite ) {
    +					break;
    +				}
    +			}
    +		}
    +		finally {
    +			outputStream.close();
    +		}
    +		return tempOutputFile;
    +	}
    +
    +	public final static File writeTemporaryFile( byte [] bytes, String prefix ) throws IOException {
    +		if ( prefix == null ) {
    +			prefix = GHIDRA_FILE_SYSTEM_PREFIX;
    +		}
    +		if ( prefix.length() < 3 ) {//temp file prefix must be at least 3 chars in length
    +			for ( int i = prefix.length() ; i < 3 ; ++i ) {
    +				prefix = prefix + '_';
    +			}
    +		}
    +		File tempFile = File.createTempFile( prefix , GHIDRA_FILE_SYSTEM_SUFFIX );
    +		tempFile.deleteOnExit();
    +		OutputStream tempFileOut = new FileOutputStream( tempFile );
    +		try {
    +			tempFileOut.write( bytes );
    +		}
    +		finally {
    +			tempFileOut.close();
    +		}
    +		return tempFile;
    +	}
    +}
    
  • GPL/DMG/src/dmg/java/mobiledevices/dmg/ghidra/GRandomAccessFile.java+306 0 added
    @@ -0,0 +1,306 @@
    +/* ###
    + * IP: Public Domain
    + */
    +package mobiledevices.dmg.ghidra;
    +
    +import java.io.*;
    +
    +/**
    + * Instances of this class support both reading and writing to a 
    + * random access file. A random access file behaves like a large 
    + * array of bytes stored in the file system. There is a kind of cursor, 
    + * or index into the implied array, called the <em>file pointer</em>.
    + * This implementation relies on java.net.RandomAccessFile,
    + * but adds buffering to limit the amount.
    + */
    +public class GRandomAccessFile {
    +	private static final byte[] EMPTY = new byte[0];
    +	private static final int BUFFER_SIZE = 0x100000;
    +
    +	private File file;
    +	private RandomAccessFile randomAccessFile;
    +	private byte[] buffer = EMPTY;
    +	private long bufferOffset = 0;
    +	private long bufferFileStartIndex = 0;
    +	private byte[] lastbuffer = EMPTY;
    +	private long lastbufferOffset = 0;
    +	private long lastbufferFileStartIndex = 0;
    +	private boolean open = false;
    +
    +	private void checkOpen() throws IOException {
    +		if (!open) {
    +			throw new IOException("GhidraRandomAccessFile is closed");
    +		}
    +	}
    +
    +	/**
    +	 * Creates a random access file stream to read from, and optionally to
    +	 * write to, the file specified by the {@link File} argument.  A new {@link
    +	 * FileDescriptor} object is created to represent this file connection.
    +	 *
    +	 * <p>
    +	 * This implementation relies on java.net.RandomAccessFile,
    +	 * but adds buffering to limit the amount.
    +	 * <p>
    +	 * 
    +	 * <a name="mode"><p> The <tt>mode</tt> argument specifies the access mode
    +	 * in which the file is to be opened.  The permitted values and their
    +	 * meanings are:
    +	 *
    +	 * <blockquote><table summary="Access mode permitted values and meanings">
    +	 * <tr><th><p align="left">Value</p></th><th><p align="left">Meaning</p></th></tr>
    +	 * <tr><td valign="top"><tt>"r"</tt></td>
    +	 *     <td> Open for reading only.  Invoking any of the <tt>write</tt>
    +	 *     methods of the resulting object will cause an {@link
    +	 *     java.io.IOException} to be thrown. </td></tr>
    +	 * <tr><td valign="top"><tt>"rw"</tt></td>
    +	 *     <td> Open for reading and writing.  If the file does not already
    +	 *     exist then an attempt will be made to create it. </td></tr>
    +	 * <tr><td valign="top"><tt>"rws"</tt></td>
    +	 *     <td> Open for reading and writing, as with <tt>"rw"</tt>, and also
    +	 *     require that every update to the file's content or metadata be
    +	 *     written synchronously to the underlying storage device.  </td></tr>
    +	 * <tr><td valign="top"><tt>"rwd"&nbsp;&nbsp;</tt></td>
    +	 *     <td> Open for reading and writing, as with <tt>"rw"</tt>, and also
    +	 *     require that every update to the file's content be written
    +	 *     synchronously to the underlying storage device. </td></tr>
    +	 * </table></blockquote>
    +	 *
    +	 * @param      file   the file object
    +	 * @param      mode   the access mode, as described
    +	 *                    <a href="#mode">above</a>
    +	 * @exception  IllegalArgumentException  if the mode argument is not equal
    +	 *               to one of <tt>"r"</tt>, <tt>"rw"</tt>, <tt>"rws"</tt>, or
    +	 *               <tt>"rwd"</tt>
    +	 * @exception FileNotFoundException
    +	 *					that name cannot be created, or if some other error occurs
    +	 *            while opening or creating the file
    +	 */
    +	public GRandomAccessFile(File file, String mode) throws IOException {
    +		this.file = file;
    +		randomAccessFile = new RandomAccessFile(file, mode);
    +		this.open = true;
    +	}
    +
    +	@Override
    +	protected void finalize() {
    +		if (open) {
    +			//TODO Msg.warn(this, "FAIL TO CLOSE " + file);
    +		}
    +	}
    +
    +	/**
    +	 * Closes this random access file stream and releases any system 
    +	 * resources associated with the stream. A closed random access 
    +	 * file cannot perform input or output operations and cannot be 
    +	 * reopened.
    +	 * <p>
    +	 * If this file has an associated channel then the channel is closed as well.
    +	 * @exception  IOException  if an I/O error occurs.
    +	 */
    +	public void close() throws IOException {
    +		checkOpen();
    +		open = false;
    +		randomAccessFile.close();
    +	}
    +
    +	/**
    +	 * Returns the length of this file.
    +	 * @return     the length of this file, measured in bytes.
    +	 * @exception  IOException  if an I/O error occurs.
    +	 */
    +	public long length() throws IOException {
    +		checkOpen();
    +		return randomAccessFile.length();
    +	}
    +
    +	/**
    +	 * Sets the file-pointer offset, measured from the beginning of this 
    +	 * file, at which the next read or write occurs.  The offset may be 
    +	 * set beyond the end of the file. Setting the offset beyond the end 
    +	 * of the file does not change the file length.  The file length will 
    +	 * change only by writing after the offset has been set beyond the end 
    +	 * of the file. 
    +	 * @param      pos   the offset position, measured in bytes from the 
    +	 *                   beginning of the file, at which to set the file 
    +	 *                   pointer.
    +	 * @throws IOException 
    +	 * @exception  IOException  if <code>pos</code> is less than 
    +	 *                          <code>0</code> or if an I/O error occurs.
    +	 */
    +	public void seek(long pos) throws IOException {
    +		checkOpen();
    +
    +		if (pos < 0) {
    +			throw new IOException("pos cannot be less than zero");
    +		}
    +
    +		if (pos < bufferFileStartIndex || pos >= bufferFileStartIndex + BUFFER_SIZE) {
    +			// check if the last buffer contained it, and swap in if necessary
    +			swapInLast();
    +			if (pos < bufferFileStartIndex || pos >= bufferFileStartIndex + BUFFER_SIZE) {
    +				// not in either, gotta get a new one
    +				buffer = EMPTY;
    +				bufferOffset = 0;
    +				bufferFileStartIndex = pos;
    +			}
    +		}
    +		bufferOffset = pos - bufferFileStartIndex;
    +	}
    +
    +	/**
    +	 * This method reads a byte from the file, starting from the current file pointer. 
    +	 * <p>
    +	 * This method blocks until the byte is read, the end of the stream 
    +	 * is detected, or an exception is thrown. 
    +	 *
    +	 * @return     the next byte of this file as a signed eight-bit
    +	 *             <code>byte</code>.
    +	 * @exception  EOFException  if this file has reached the end.
    +	 * @exception  IOException   if an I/O error occurs.
    +	 */
    +	public byte readByte() throws IOException {
    +		checkOpen();
    +		ensure(1);
    +		return buffer[(int) bufferOffset];
    +	}
    +
    +	/**
    +	 * Reads up to <code>b.length</code> bytes of data from this file 
    +	 * into an array of bytes. This method blocks until at least one byte 
    +	 * of input is available. 
    +	 *
    +	 * @param      b   the buffer into which the data is read.
    +	 * @return     the total number of bytes read into the buffer, or
    +	 *             <code>-1</code> if there is no more data because the end of
    +	 *             this file has been reached.
    +	 * @exception  IOException  if an I/O error occurs.
    +	 */
    +	public int read(byte[] b) throws IOException {
    +		checkOpen();
    +		return read(b, 0, b.length);
    +	}
    +
    +	/**
    +	 * Reads up to <code>len</code> bytes of data from this file into an 
    +	 * array of bytes. This method blocks until at least one byte of input 
    +	 * is available.
    +	 * 
    +	 * @param      b     the buffer into which the data is read.
    +	 * @param      off   the start offset of the data.
    +	 * @param      len   the maximum number of bytes read.
    +	 * @return     the total number of bytes read into the buffer, or
    +	 *             <code>-1</code> if there is no more data because the end of
    +	 *             the file has been reached.
    +	 * @exception  IOException  if an I/O error occurs.
    +	 */
    +	public int read(byte[] b, int offset, int length) throws IOException {
    +		checkOpen();
    +		int readLen = length;
    +		do {
    +			int blocklength = readLen;
    +			if (readLen > (BUFFER_SIZE - bufferOffset)) {
    +				blocklength = (BUFFER_SIZE - (int) bufferOffset);
    +				if (blocklength <= 0) {
    +					blocklength = BUFFER_SIZE;
    +				}
    +			}
    +			ensure(blocklength);
    +			System.arraycopy(buffer, (int) bufferOffset, b, offset, blocklength);
    +			readLen -= blocklength;
    +			offset += blocklength;
    +			if (readLen > 0) {
    +				seek(this.bufferFileStartIndex + bufferOffset + blocklength);
    +			}
    +		}
    +		while (readLen > 0);
    +		return length;
    +	}
    +
    +	/**
    +	 * Writes a byte to this file, starting at the current file pointer. 
    +	 * @param      b   the data.
    +	 * @exception  IOException  if an I/O error occurs.
    +	 */
    +	public void write(byte b) throws IOException {
    +		checkOpen();
    +		write(new byte[] { b }, 0, 1);
    +	}
    +
    +	/**
    +	 * Writes <code>b.length</code> bytes from the specified byte array 
    +	 * to this file, starting at the current file pointer. 
    +	 * @param      b   the data.
    +	 * @exception  IOException  if an I/O error occurs.
    +	 */
    +	public void write(byte[] b) throws IOException {
    +		checkOpen();
    +		write(b, 0, b.length);
    +	}
    +
    +	/**
    +	 * Writes a sub array as a sequence of bytes. 
    +	 * @param b the data to be written
    +	 * @param offset the start offset in the data
    +	 * @param length the number of bytes that are written
    +	 * @exception IOException If an I/O error has occurred.
    +	 */
    +	public void write(byte[] b, int offset, int length) throws IOException {
    +		checkOpen();
    +		randomAccessFile.write(b, offset, length);
    +		buffer = EMPTY;
    +		bufferOffset = 0;
    +		lastbuffer = EMPTY;
    +		lastbufferOffset = 0;
    +	}
    +
    +	/**
    +	 * Ensures that enough bytes are cached to
    +	 * satisfy the next request to read.
    +	 */
    +	private void ensure(int bytesNeeded) throws IOException {
    +		checkOpen();
    +		long oldFileStartIndex = bufferFileStartIndex;
    +		long oldBufferOffset = bufferOffset;
    +		long oldSeekPos = oldFileStartIndex + oldBufferOffset;
    +
    +		if (bufferOffset + bytesNeeded > buffer.length) {
    +			// check if the last buffer contained it, and swap in if necessary
    +			swapInLast();
    +			// must ensure that current read pos is in old buffer, and enough bytes
    +			long newBufferOffset = (oldSeekPos - bufferFileStartIndex);
    +			if (oldSeekPos < bufferFileStartIndex ||
    +				oldSeekPos >= bufferFileStartIndex + BUFFER_SIZE ||
    +				(newBufferOffset + bytesNeeded > buffer.length)) {
    +				bufferFileStartIndex = oldFileStartIndex + oldBufferOffset;
    +
    +				buffer = new byte[BUFFER_SIZE];
    +				randomAccessFile.seek(bufferFileStartIndex);
    +				randomAccessFile.read(buffer);
    +				bufferOffset = 0;
    +			}
    +			else {
    +				bufferOffset = newBufferOffset;
    +			}
    +		}
    +	}
    +
    +	private void swapInLast() throws IOException {
    +		checkOpen();
    +		if (buffer == EMPTY) {
    +			return;
    +		}
    +		// swap em and return
    +		byte[] swapbuffer = buffer;
    +		long swapbufferOffset = bufferOffset;
    +		long swapbufferFileStartIndex = bufferFileStartIndex;
    +
    +		buffer = lastbuffer;
    +		bufferOffset = lastbufferOffset;
    +		bufferFileStartIndex = lastbufferFileStartIndex;
    +
    +		lastbuffer = swapbuffer;
    +		lastbufferOffset = swapbufferOffset;
    +		lastbufferFileStartIndex = swapbufferFileStartIndex;
    +	}
    +}
    
  • GPL/DMG/src/dmg/java/mobiledevices/dmg/ghidra/GStringUtilities.java+58 0 added
    @@ -0,0 +1,58 @@
    +/* ###
    + * IP: Public Domain
    + */
    +package mobiledevices.dmg.ghidra;
    +
    +
    +/**
    + * Class with static methods that deal with string manipulation. 
    + */
    +public class GStringUtilities {
    +
    +	/**
    +	 * Converts an integer into a string.
    +	 * For example, given an integer 0x41424344,
    +	 * the returned string would be "ABCD".
    +	 * @param value the integer value
    +	 * @return the converted string
    +	 */
    +	public static String toString(int value) {
    +		byte[] bytes = new byte[4];
    +		int byteIndex = bytes.length - 1;
    +		while (value != 0) {
    +			bytes[byteIndex] = (byte) value;
    +			value = value >> 8;
    +			--byteIndex;
    +		}
    +		return new String(bytes);
    +	}
    +
    +	public static String convertBytesToString( byte [] bytes, int length ) {
    +		StringBuffer buf = new StringBuffer( length * 2);
    +		for ( int i = 0 ; i < length ; ++i ) {
    +			String bs = Integer.toHexString( bytes[ i ] & 0xff );
    +			if ( bs.length() == 1 ) {
    +				buf.append( "0" );
    +			}
    +			buf.append( bs );
    +		}
    +		return buf.toString();
    +	}
    +
    +	public static byte[] convertStringToBytes(String hexstr) {
    +		try {
    +			byte[] bytes = new byte[hexstr.length() / 2];
    +			for (int i = 0; i < hexstr.length(); i += 2) {
    +				String bs = hexstr.substring(i, i + 2);
    +				bytes[i / 2] = (byte) Integer.parseInt(bs, 16);
    +			}
    +			return bytes;
    +		}
    +		catch (Exception e) {
    +			// tried, but failed
    +		}
    +		return null;
    +	}
    +
    +}
    +
    
  • GPL/DMG/src/dmg/java/mobiledevices/dmg/ghidra/GSystemUtilities.java+16 0 added
    @@ -0,0 +1,16 @@
    +/* ###
    + * IP: Public Domain
    + */
    +package mobiledevices.dmg.ghidra;
    +
    +
    +public class GSystemUtilities {
    +
    +	public static boolean isEqual(Object o1, Object o2) {
    +		if (o1 == null) {
    +			return (o2 == null);
    +		}
    +		return o1.equals(o2);
    +	}
    +
    +}
    
  • GPL/DMG/src/dmg/java/mobiledevices/dmg/hfsplus/AttributesFileParser.java+125 0 added
    @@ -0,0 +1,125 @@
    +/* ###
    + * IP: Public Domain
    + */
    +package mobiledevices.dmg.hfsplus;
    +
    +import java.io.*;
    +import java.util.HashMap;
    +import java.util.Map;
    +
    +import org.catacombae.hfsexplorer.fs.ImplHFSXFileSystemView;
    +import org.catacombae.hfsexplorer.fs.NullProgressMonitor;
    +import org.catacombae.hfsexplorer.types.hfscommon.CommonHFSCatalogFile;
    +import org.catacombae.hfsexplorer.types.hfscommon.CommonHFSForkData;
    +import org.catacombae.hfsexplorer.types.hfsplus.*;
    +import org.catacombae.jparted.lib.fs.FSFile;
    +import org.catacombae.jparted.lib.fs.hfscommon.HFSCommonFSFile;
    +import org.catacombae.jparted.lib.fs.hfsx.HFSXFileSystemHandler;
    +
    +import mobiledevices.dmg.btree.*;
    +import mobiledevices.dmg.decmpfs.DecmpfsHeader;
    +import mobiledevices.dmg.ghidra.GBinaryReader;
    +import mobiledevices.dmg.ghidra.GByteProvider;
    +
    +/**
    + * This code will extract the attributes file from the HFS+ file system,
    + * which contains the B-tree for traversing the DECOMPFS files.
    + */
    +public class AttributesFileParser {
    +
    +	private Map<FSFile, DecmpfsHeader> map = new HashMap<FSFile, DecmpfsHeader>();
    +	private GByteProvider provider;
    +	private BTreeRootNodeDescriptor root;
    +
    +	public AttributesFileParser( HFSXFileSystemHandler handler, String prefix ) throws IOException {
    +
    +        ImplHFSXFileSystemView hfsxFileSystemView = (ImplHFSXFileSystemView) handler.getFSView();
    +        HFSPlusVolumeHeader volumeHeader = hfsxFileSystemView.getHFSPlusVolumeHeader();
    +
    +        HFSPlusForkData attributes = volumeHeader.getAttributesFile();
    +
    +       	File attributesFile = writeVolumeHeaderFile( hfsxFileSystemView, attributes, prefix + "_" + "attributesFile" );
    +
    +		provider = new GByteProvider( attributesFile );
    +
    +       	if ( attributesFile.length() == 0 ) {
    +       		return;
    +       	}
    +
    +		GBinaryReader reader = new GBinaryReader( provider, false );
    +
    +        root = new BTreeRootNodeDescriptor( reader );
    +	}
    +
    +	public void dispose() throws IOException {
    +		map.clear();
    +		provider.close();
    +	}
    +
    +	private int getFileID(FSFile file) {
    +		try {
    +		    HFSCommonFSFile hfsFile = (HFSCommonFSFile)file;
    +		    CommonHFSCatalogFile catalogFile = hfsFile.getInternalCatalogFile();
    +		    CommonHFSCatalogFile.HFSPlusImplementation hfsPlusCatalogFile = (CommonHFSCatalogFile.HFSPlusImplementation)catalogFile;
    +		    HFSPlusCatalogFile underlying = hfsPlusCatalogFile.getUnderlying();
    +		    HFSCatalogNodeID fileID = underlying.getFileID();
    +		    return fileID.toInt();
    +		}
    +		catch (Exception e) {
    +			return -1;
    +		}
    +	}
    +
    +	private File writeVolumeHeaderFile( ImplHFSXFileSystemView hfsxFileSystemView, 
    +										HFSPlusForkData volumeHeaderFile, 
    +										String volumeHeaderFileName ) throws IOException {
    +
    +		if (volumeHeaderFile == null) {
    +			return null;
    +		}
    +
    +		File file = File.createTempFile( "Ghidra_" + volumeHeaderFileName + "_", ".tmp" );
    +		file.deleteOnExit();
    +		OutputStream out = new FileOutputStream( file );
    +		try {
    +			CommonHFSForkData fork = CommonHFSForkData.create( volumeHeaderFile );
    +			hfsxFileSystemView.extractForkToStream( fork, fork.getBasicExtents(), out, new NullProgressMonitor() {} );
    +		}
    +		finally {
    +			out.close();
    +		}
    +		return file;
    +	}
    +	
    +	public DecmpfsHeader getDecmpfsHeader(FSFile file) throws IOException {
    +
    +		if ( root == null ) {
    +			return null;
    +		}
    +
    +		if ( map.get( file ) != null ) {
    +			return map.get( file );
    +		}
    +
    +		int fileID = getFileID( file );
    +
    +		if ( fileID == -1 ) {
    +			return null;
    +		}
    +
    +        for ( BTreeNodeDescriptor node : root.getNodes() ) {
    +			for ( BTreeNodeRecord record : node.getRecords() ) {
    +				if ( record.getFileID() == fileID ) {
    +					DecmpfsHeader header = record.getDecmpfsHeader();
    +					if ( header != null ) {
    +						map.put( file, header );
    +						return header;
    +					}
    +				}
    +			}
    +        }
    +        return null;
    +	}
    +
    +	
    +}
    
  • GPL/DMG/src/dmg/java/mobiledevices/dmg/reader/DmgFileReader.java+344 0 added
    @@ -0,0 +1,344 @@
    +/* ###
    + * IP: Public Domain
    + */
    +package mobiledevices.dmg.reader;
    +
    +import java.io.*;
    +import java.util.ArrayList;
    +import java.util.List;
    +
    +import org.catacombae.dmgextractor.encodings.encrypted.ReadableCEncryptedEncodingStream;
    +import org.catacombae.hfsexplorer.FileSystemRecognizer;
    +import org.catacombae.hfsexplorer.PartitionSystemRecognizer;
    +import org.catacombae.hfsexplorer.UDIFRecognizer;
    +import org.catacombae.hfsexplorer.partitioning.Partition;
    +import org.catacombae.hfsexplorer.partitioning.PartitionSystem;
    +import org.catacombae.hfsexplorer.win32.WindowsLowLevelIO;
    +import org.catacombae.io.*;
    +import org.catacombae.jparted.lib.DataLocator;
    +import org.catacombae.jparted.lib.ReadableStreamDataLocator;
    +import org.catacombae.jparted.lib.fs.*;
    +import org.catacombae.jparted.lib.fs.FileSystemHandlerFactory.StandardAttribute;
    +import org.catacombae.jparted.lib.fs.hfsx.HFSXFileSystemHandler;
    +import org.catacombae.udif.UDIFFile;
    +import org.catacombae.udif.UDIFRandomAccessStream;
    +
    +import mobiledevices.dmg.decmpfs.DecmpfsCompressionTypes;
    +import mobiledevices.dmg.decmpfs.DecmpfsHeader;
    +import mobiledevices.dmg.ghidra.*;
    +import mobiledevices.dmg.hfsplus.AttributesFileParser;
    +import mobiledevices.dmg.zlib.ZLIB;
    +
    +public class DmgFileReader implements Closeable {
    +	private final static GDataConverter ledc = new GDataConverterLE();
    +	private final static GDataConverter bedc = new GDataConverterBE();
    +
    +	private GByteProvider provider;
    +	private AttributesFileParser parser;
    +	private ReadableRandomAccessStream rras;
    +	private List<FSFolder> rootFolders = new ArrayList<FSFolder>();
    +	private List<FileSystemHandler> fileSystemHandlers = new ArrayList<FileSystemHandler>();
    +
    +	public DmgFileReader( GByteProvider provider ) {
    +		this.provider = provider;
    +	}
    +
    +	public void open() throws IOException {
    +
    +		File file = provider.getFile();
    +
    +		if (WindowsLowLevelIO.isSystemSupported()) {
    +			rras = new WindowsLowLevelIO(file.getAbsolutePath());
    +		}
    +		else {
    +			rras = new ReadableFileStream(file.getAbsolutePath());
    +		}
    +
    +		if (ReadableCEncryptedEncodingStream.isCEncryptedEncoding(rras)) {
    +			//TODO use our decryption instead??
    +		}
    +
    +		System.err.println("Trying to detect UDIF structure...");
    +		if (UDIFRecognizer.isUDIF(rras)) {
    +			System.err.println("UDIF structure found! Creating filter stream...");
    +
    +			UDIFFile udifFile = new UDIFFile(new ReadableFileStream(file.getAbsolutePath()));
    +			debug(udifFile.getView().getPlistData(), "dmg-xml");
    +
    +			UDIFRandomAccessStream stream = new UDIFRandomAccessStream(rras);
    +			rras = stream;
    +		}
    +		else {
    +			System.err.println("UDIF structure not found. Proceeding...");
    +		}
    +
    +		PartitionSystemRecognizer partitionSystemRecognizer = new PartitionSystemRecognizer(rras);
    +		PartitionSystem partitionSystem = partitionSystemRecognizer.getPartitionSystem();
    +
    +		if (partitionSystem == null) {
    +			throw new IOException("No system partitions found. Perhaps the decryption failed?");
    +		}
    +
    +		Partition[] partitions = partitionSystem.getUsedPartitionEntries();
    +		for (Partition partition : partitions) {
    +			openPartition(partition);
    +		}
    +	}
    +
    +	private void debug( byte [] plistData, String fileName ) {
    +		// TODO Auto-generated method stub
    +	}
    +
    +	private void openPartition( Partition selectedPartition ) throws IOException {
    +        long fsOffset = selectedPartition.getStartOffset();//getPmPyPartStart()+selectedPartition.getPmLgDataStart())*blockSize;
    +        long fsLength = selectedPartition.getLength();//getPmDataCnt()*blockSize;
    +
    +        FileSystemRecognizer fsr = new FileSystemRecognizer( rras, fsOffset );
    +        FileSystemRecognizer.FileSystemType fsType = fsr.detectFileSystem();
    +
    +        if ( fsType == FileSystemRecognizer.FileSystemType.HFS_PLUS ||
    +        	 fsType == FileSystemRecognizer.FileSystemType.HFSX ||
    +        	 fsType == FileSystemRecognizer.FileSystemType.HFS ) {
    +
    +            final FileSystemMajorType fsMajorType;
    +            switch ( fsType ) {
    +                case HFS:
    +                    fsMajorType = FileSystemMajorType.APPLE_HFS;
    +                    break;
    +                case HFS_PLUS:
    +                    fsMajorType = FileSystemMajorType.APPLE_HFS_PLUS;
    +                    break;
    +                case HFSX:
    +                    fsMajorType = FileSystemMajorType.APPLE_HFSX;
    +                    break;
    +                default:
    +                    fsMajorType = null;
    +                    break;
    +            }
    +
    +            FileSystemHandlerFactory factory = fsMajorType.createDefaultHandlerFactory();
    +            if ( factory.isSupported( StandardAttribute.CACHING_ENABLED ) ) {
    +                factory.getCreateAttributes().
    +                        setBooleanAttribute(StandardAttribute.CACHING_ENABLED,
    +                        true);
    +            }
    +
    +            ReadableRandomAccessStream stage1;
    +
    +            if (fsLength > 0) {
    +            	stage1 = new ReadableConcatenatedStream(rras, fsOffset, fsLength);
    +            }
    +            else {
    +            	stage1 = rras;
    +            }
    +
    +            DataLocator dataLocator = new ReadableStreamDataLocator(stage1);
    +
    +            FileSystemHandler fileSystemHandler = factory.createHandler(dataLocator);
    +            fileSystemHandlers.add( fileSystemHandler );
    +
    +            rootFolders.add( fileSystemHandler.getRoot() );
    +
    +            if ( fileSystemHandler instanceof HFSXFileSystemHandler ) {
    +            	parser = new AttributesFileParser( (HFSXFileSystemHandler)fileSystemHandler, fileSystemHandler.getRoot( ).getName( ) );
    +            }
    +        } else {
    +        		System.err.println("UNKNOWN file system type.  Can't Open filesystem.  Suspect this is an APFS.\n");
    +        }
    +	}
    +
    +	@Override
    +	public void close() throws IOException {
    +		try {
    +			rras.close();
    +		}
    +		catch (Exception e) {
    +			//ignore
    +		}
    +		if ( parser != null ) {
    +			parser.dispose();
    +			parser = null;
    +		}
    +		fileSystemHandlers.clear();
    +		rootFolders.clear();
    +	}
    +
    +	public InputStream getData( FSEntry entry ) throws IOException {
    +		if ( entry != null && entry.isFile() ) {
    +			FSFile fsFile = (FSFile)entry;
    +			FSFork mainFork = fsFile.getMainFork();
    +			if ( mainFork.getLength() > 0 ) {
    +				ReadableRandomAccessStream mainForkStream = mainFork.getReadableRandomAccessStream();
    +				if ( mainForkStream.length() != 0 ) {
    +					return new DmgInputStream( mainForkStream );
    +				}
    +			}
    +			else if ( mainFork.getLength() == 0 ) {
    +
    +				FSFork resourceFork = fsFile.getForkByType( FSForkType.MACOS_RESOURCE );
    +				ReadableRandomAccessStream resourceForkStream = resourceFork.getReadableRandomAccessStream();
    +
    +				if ( parser == null ) {
    +					return null;
    +				}
    +
    +				DecmpfsHeader decmpfsHeader = parser.getDecmpfsHeader( fsFile );
    +
    +				if ( decmpfsHeader == null ) {
    +					return null;
    +				}
    +
    +				if ( decmpfsHeader.getCompressionType() == DecmpfsCompressionTypes.CMP_Type3 ) {
    +
    +					if ( decmpfsHeader.getAttrBytes()[ 0 ] == -1 ) {
    +						return new ByteArrayInputStream( decmpfsHeader.getAttrBytes(), 1, decmpfsHeader.getAttrBytes().length - 1 );
    +					}
    +
    +					ZLIB zlib = new ZLIB();
    +
    +					InputStream inputStream =
    +						new ByteArrayInputStream(decmpfsHeader.getAttrBytes());
    +
    +					ByteArrayOutputStream uncompressedBytes =
    +						zlib.decompress(inputStream, (int) decmpfsHeader.getUncompressedSize());
    +
    +					File tempDecompressedFile = GFileUtilityMethods.writeTemporaryFile(
    +						uncompressedBytes.toByteArray(), entry.getName());
    +					return new FileInputStream(tempDecompressedFile);
    +				}
    +				else if ( decmpfsHeader.getCompressionType() == DecmpfsCompressionTypes.CMP_Type4 ) {
    +
    +					return decompressResourceFork( entry, resourceForkStream, (int)decmpfsHeader.getUncompressedSize() );
    +				}
    +			}
    +		}
    +		return null;
    +	}
    +
    +	private InputStream decompressResourceFork( FSEntry entry, 
    +												ReadableRandomAccessStream resourceForkStream,
    +												int expectedLength ) throws IOException {
    +
    +		File tempFile = GFileUtilityMethods.writeTemporaryFile( new DmgInputStream( resourceForkStream ) );
    +		System.err.println(
    +			"dmg resource fork for " + entry.getName() + ": " + tempFile.getAbsolutePath());
    +
    +		InputStream input = new FileInputStream( tempFile );
    +
    +		for ( int i = 0 ; i < 0x100 ; ++i ) {
    +			input.read();
    +		}
    +
    +		byte [] sizeBytes = new byte[ 4 ];
    +		input.read( sizeBytes );
    +		int size = sizeBytes[ 0 ] == 0 ? 
    +							bedc.getInt( sizeBytes ) : 
    +							ledc.getInt( sizeBytes );
    +
    +		byte [] flagsBytes = new byte[ 4 ];
    +		input.read( flagsBytes );
    +
    +		byte [] startDistanceBytes = new byte[ 4 ];
    +		input.read( startDistanceBytes );
    +		int startDistance = ledc.getInt( startDistanceBytes );
    +
    +		input.skip( startDistance - 8 );//skip to the start of the zlib compressed file
    +
    +		File tempCompressedFile = GFileUtilityMethods.writeTemporaryFile( input, size - startDistance );
    +		InputStream inputStream = new FileInputStream( tempCompressedFile );
    +
    +		ZLIB zlib = new ZLIB( );
    +		ByteArrayOutputStream uncompressedByteStream = zlib.decompress( inputStream, expectedLength );
    +
    +		return new ByteArrayInputStream( uncompressedByteStream.toByteArray() );
    +	}
    +
    +	public List<String> getInfo( String path ) {
    +		if ( path != null ) {
    +			DmgInfoGenerator info = new DmgInfoGenerator( this, path, parser );
    +			return info.getInformation( );
    +		}
    +		return null;
    +	}
    +
    +	public List<FSEntry> getListing( String path ) {
    +		List<FSEntry> list = new ArrayList<FSEntry>();
    +		if ( path == null || path.equals( "/" ) ) {
    +			for ( FileSystemHandler handler : fileSystemHandlers ) {
    +				list.add( handler.getRoot() );
    +			}
    +		}
    +		else {
    +			FSEntry fileByPath = getFileByPath( path );
    +			if ( fileByPath != null ) {
    +				if ( fileByPath.isFolder() ) {
    +					FSEntry [] listEntries = fileByPath.asFolder().listEntries();
    +					for ( FSEntry entry : listEntries ) {
    +						list.add( entry );
    +					}
    +				}
    +			}
    +		}
    +		return list;
    +	}
    +
    +	/**
    +	 * Returns the length of the given file system entry.
    +	 * If the entry is actually a directory, then -1 is returned.
    +	 */
    +	public long getLength( FSEntry entry ) {
    +		if ( entry != null & entry.isFile() ) {
    +			FSFork mainFork = entry.asFile().getMainFork();
    +			if ( mainFork.getLength() > 0 ) {
    +				return mainFork.getLength();
    +			}
    +			try {
    +				if (parser != null) {
    +					DecmpfsHeader header = parser.getDecmpfsHeader(entry.asFile());
    +					if (header != null) {
    +						return header.getUncompressedSize();
    +					}
    +				}
    +			}
    +			catch (IOException e) {
    +				return 1;//TODO lookup valid length in DECMPFS
    +			}
    +		}
    +		return -1;
    +	}
    +
    +	/**
    +	 * Convert path to string array.
    +	 * 
    +	 * For example, "/a/b/c.txt" will be converted to [ "a", "b", "c.txt" ].
    +	 * 
    +	 * Note: the "a" will be stripped because it corresponds to the file system handler.
    +	 */
    +	public String [] convertPathToArrayAndStripFileSystemName( String path ) {
    +		String [] splitPath = path.split( "/" );
    +		if ( splitPath.length <= 2 ) {
    +			return new String[ 0 ];
    +		}
    +		String [] temp = new String[ splitPath.length - 2 ];
    +		System.arraycopy( splitPath, 2, temp, 0, splitPath.length - 2 );
    +		return temp;
    +	}
    +
    +	/**
    +	 * Returns the DMG file object for the corresponding path.
    +	 * Path should contain the file system handler name.
    +	 */
    +	public FSEntry getFileByPath( String path ) {
    +		if ( path == null || path.equals( "/" ) ) {//ROOT
    +			return null;
    +		}
    +		for ( FileSystemHandler handler : fileSystemHandlers ) {
    +			FSEntry entry = handler.getEntry( convertPathToArrayAndStripFileSystemName( path ) );
    +			if ( entry != null ) {
    +				return entry;
    +			}
    +		}
    +		return null;
    +	}
    +
    +}
    
  • GPL/DMG/src/dmg/java/mobiledevices/dmg/reader/DmgInfoGenerator.java+223 0 added
    @@ -0,0 +1,223 @@
    +/* ###
    + * IP: Public Domain
    + */
    +package mobiledevices.dmg.reader;
    +
    +import java.io.IOException;
    +import java.text.DateFormat;
    +import java.util.ArrayList;
    +import java.util.List;
    +
    +import org.catacombae.hfsexplorer.ObjectContainer;
    +import org.catacombae.hfsexplorer.types.hfscommon.CommonHFSCatalogFile;
    +import org.catacombae.hfsexplorer.types.hfsplus.HFSCatalogNodeID;
    +import org.catacombae.hfsexplorer.types.hfsplus.HFSPlusCatalogFile;
    +import org.catacombae.jparted.lib.fs.*;
    +import org.catacombae.jparted.lib.fs.FSAttributes.POSIXFileAttributes;
    +import org.catacombae.jparted.lib.fs.hfscommon.HFSCommonFSFile;
    +
    +import mobiledevices.dmg.decmpfs.DecmpfsHeader;
    +import mobiledevices.dmg.hfsplus.AttributesFileParser;
    +
    +/**
    + * 
    + * @see org.catacombae.hfsexplorer.gui.FSEntrySummaryPanel
    + *
    + */
    +class DmgInfoGenerator {
    +	private DmgFileReader fileSystem;
    +	private String filePath;
    +	private AttributesFileParser parser;
    +	private FSEntry entry;
    +	private DateFormat df = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM);
    +
    +	DmgInfoGenerator(DmgFileReader fileSystem, String filePath, AttributesFileParser parser) {
    +		this.fileSystem = fileSystem;
    +		this.filePath = filePath;
    +		this.parser = parser;
    +		this.entry = fileSystem.getFileByPath(filePath);
    +	}
    +
    +	List<String> getInformation() {
    +		List<String> infoList = new ArrayList<String>();
    +
    +		if (entry == null) {
    +			infoList.add("<< no information available >>");
    +			return infoList;
    +		}
    +
    +		infoList.add("Name: " + entry.getName());
    +
    +		if (entry instanceof FSFile) {
    +			FSFile file = (FSFile) entry;
    +			infoList.add("Type: " + "File");
    +			infoList.add("Total Size: " + getSizeString(file.getCombinedLength()));
    +			FSFork[] allForks = file.getAllForks();
    +			for (FSFork fork : allForks) {
    +				infoList.add(
    +					"    " + fork.getForkIdentifier() + ": " + getSizeString(fork.getLength()));
    +			}
    +			appendFileID(infoList, file);
    +
    +			if (parser != null) {
    +				try {
    +					DecmpfsHeader decmpfsHeader = parser.getDecmpfsHeader(file);
    +					if (decmpfsHeader != null) {
    +						infoList.add(
    +							"Decmpfs Size: " + getSizeString(decmpfsHeader.getUncompressedSize()));
    +					}
    +				}
    +				catch (IOException e) {
    +				}
    +			}
    +		}
    +		else if (entry instanceof FSFolder) {
    +			FSFolder folder = (FSFolder) entry;
    +			infoList.add("Type: " + "Folder");
    +			infoList.add("Size: " + startFolderSizeCalculation(folder));
    +		}
    +		else if (entry instanceof FSLink) {
    +			FSLink link = (FSLink) entry;
    +
    +			FSEntry linkTarget =
    +				link.getLinkTarget(fileSystem.convertPathToArrayAndStripFileSystemName(filePath));
    +			if (linkTarget == null) {
    +				infoList.add("Type: " + "Symbolic link (broken)");
    +				infoList.add("Size: " + "- (broken link)");
    +			}
    +			else if (linkTarget instanceof FSFile) {
    +				FSFile file = (FSFile) linkTarget;
    +				infoList.add("Type: " + "Symbolic link (file)");
    +				infoList.add("Size: " + getSizeString(file.getMainFork().getLength()));
    +				FSFork[] allForks = file.getAllForks();
    +				for (FSFork fork : allForks) {
    +					infoList.add(
    +						"    " + fork.getForkIdentifier() + ": " + getSizeString(fork.getLength()));
    +				}
    +			}
    +			else if (linkTarget instanceof FSFolder) {
    +				FSFolder folder = (FSFolder) linkTarget;
    +				infoList.add("Type: " + "Symbolic link (folder)");
    +				infoList.add("Size: " + startFolderSizeCalculation(folder));
    +			}
    +			else {
    +				infoList.add("Type: " + "Symbolic link (unknown [" + linkTarget.getClass() + "])");
    +				infoList.add("Size: " + "- (unknown type)");
    +			}
    +			infoList.add("Link Target: " + link.getLinkTargetString());
    +		}
    +		else {
    +			infoList.add("Type: " + "Unknown [" + entry.getClass() + "]");
    +			infoList.add("Size: " + "- (unknown size)");
    +		}
    +
    +		FSAttributes attrs = entry.getAttributes();
    +
    +		appendDateInformation(attrs, infoList);
    +		appendPosixInformation(attrs, infoList);
    +		appendWindowsInformation(attrs, infoList);
    +
    +		return infoList;
    +	}
    +
    +	private void appendFileID(List<String> infoList, FSFile file) {
    +		try {
    +			HFSCommonFSFile hfsFile = (HFSCommonFSFile) file;
    +			CommonHFSCatalogFile catalogFile = hfsFile.getInternalCatalogFile();
    +			CommonHFSCatalogFile.HFSPlusImplementation hfsPlusCatalogFile =
    +				(CommonHFSCatalogFile.HFSPlusImplementation) catalogFile;
    +			HFSPlusCatalogFile underlying = hfsPlusCatalogFile.getUnderlying();
    +			HFSCatalogNodeID fileID = underlying.getFileID();
    +			infoList.add("File ID: 0x" + Integer.toHexString(fileID.toInt()));
    +		}
    +		catch (Exception e) {
    +			infoList.add("Unable to obtain file ID. " + e.getMessage());
    +		}
    +	}
    +
    +	private void appendPosixInformation(FSAttributes attrs, List<String> infoList) {
    +		if (attrs.hasPOSIXFileAttributes()) {
    +			POSIXFileAttributes posixAttrs = attrs.getPOSIXFileAttributes();
    +			infoList.add("Permissions: " + posixAttrs.getPermissionString());
    +			infoList.add("User ID:     " + posixAttrs.getUserID());
    +			infoList.add("Group ID:    " + posixAttrs.getGroupID());
    +		}
    +	}
    +
    +	private void appendWindowsInformation(FSAttributes attrs, List<String> infoList) {
    +		if (attrs.hasWindowsFileAttributes()) {
    +			WindowsFileAttributes windowsFileAttributes = attrs.getWindowsFileAttributes();
    +			infoList.add("Archive:    " + windowsFileAttributes.isArchive());
    +			infoList.add("Compressed: " + windowsFileAttributes.isCompressed());
    +			infoList.add("Directory:  " + windowsFileAttributes.isDirectory());
    +			infoList.add("Encrypted:  " + windowsFileAttributes.isEncrypted());
    +			infoList.add("Hidden:     " + windowsFileAttributes.isHidden());
    +			infoList.add("Normal:     " + windowsFileAttributes.isNormal());
    +			infoList.add("Off-line:   " + windowsFileAttributes.isOffline());
    +			infoList.add("Read-only:  " + windowsFileAttributes.isReadOnly());
    +			infoList.add("Reparse:    " + windowsFileAttributes.isReparsePoint());
    +			infoList.add("Sparse:     " + windowsFileAttributes.isSparseFile());
    +			infoList.add("System:     " + windowsFileAttributes.isSystem());
    +			infoList.add("Temp:       " + windowsFileAttributes.isTemporary());
    +			infoList.add("Virtual:    " + windowsFileAttributes.isVirtual());
    +		}
    +	}
    +
    +	private void appendDateInformation(FSAttributes attributes, List<String> infoList) {
    +		if (attributes.hasCreateDate()) {
    +			infoList.add("Created: " + df.format(attributes.getCreateDate()));
    +		}
    +		if (attributes.hasModifyDate()) {
    +			infoList.add("Contents Modified: " + df.format(attributes.getModifyDate()));
    +		}
    +		if (attributes.hasAttributeModifyDate()) {
    +			infoList.add("Attributes Modified: " + df.format(attributes.getAttributeModifyDate()));
    +		}
    +		if (attributes.hasAccessDate()) {
    +			infoList.add("Last Accessed: " + df.format(attributes.getAccessDate()));
    +		}
    +		if (attributes.hasBackupDate()) {
    +			infoList.add("Last Backup: " + df.format(attributes.getBackupDate()));
    +		}
    +	}
    +
    +	private String getSizeString(long result) {
    +		String baseString = Long.toString(result);
    +		return baseString + " bytes";
    +	}
    +
    +	private String startFolderSizeCalculation(FSFolder folder) {
    +		String resultString;
    +		try {
    +			ObjectContainer<Long> result = new ObjectContainer<Long>((long) 0);
    +			calculateFolderSize(folder, result);
    +			resultString = getSizeString(result.o);
    +		}
    +		catch (Exception e) {
    +			e.printStackTrace();
    +			resultString = "Exception while calculating! See debug console for info...";
    +		}
    +		return resultString;
    +	}
    +
    +	private void calculateFolderSize(FSFolder folder, ObjectContainer<Long> result) {
    +		for (FSEntry entry : folder.listEntries()) {
    +			if (entry instanceof FSFile) {
    +				Long value = result.o;
    +				value += ((FSFile) entry).getMainFork().getLength();
    +				result.o = value;
    +			}
    +			else if (entry instanceof FSFolder) {
    +				calculateFolderSize((FSFolder) entry, result);
    +			}
    +			else if (entry instanceof FSLink) {
    +				/* Do nothing. Symbolic link targets aren't part of the folder. */
    +			}
    +			else {
    +				System.err.println("FSEntrySummaryPanel.calculateFolderSize():" +
    +					" unexpected type " + entry.getClass());
    +			}
    +		}
    +	}
    +
    +}
    
  • GPL/DMG/src/dmg/java/mobiledevices/dmg/reader/DmgInputStream.java+43 0 added
    @@ -0,0 +1,43 @@
    +/* ###
    + * IP: Public Domain
    + */
    +package mobiledevices.dmg.reader;
    +
    +import java.io.IOException;
    +import java.io.InputStream;
    +
    +import org.catacombae.io.ReadableRandomAccessStream;
    +
    +/**
    + * A class to wrap a ReadableRandomAccessStream
    + * so it may be used as a conventional
    + * input stream.
    + */
    +public class DmgInputStream extends InputStream {
    +	private ReadableRandomAccessStream stream;
    +
    +	DmgInputStream(ReadableRandomAccessStream stream) {
    +		this.stream = stream;
    +	}
    +
    +	public long getLength() {
    +		return stream.length();
    +	}
    +
    +	@Override
    +	public int read() throws IOException {
    +		return stream.read();
    +	}
    +
    +	@Override
    +	public int read(byte [] b) throws IOException {
    +		return stream.read(b);
    +	}
    +
    +	@Override
    +	public int read(byte [] b, int off, int len) throws IOException {
    +		return stream.read(b, off, len);
    +	}
    +
    +	
    +}
    
  • GPL/DMG/src/dmg/java/mobiledevices/dmg/server/DmgServer.java+193 0 added
    @@ -0,0 +1,193 @@
    +/* ###
    + * IP: Public Domain
    + */
    +package mobiledevices.dmg.server;
    +
    +import java.io.*;
    +import java.util.List;
    +
    +import org.catacombae.jparted.lib.fs.*;
    +
    +import mobiledevices.dmg.ghidra.GByteProvider;
    +import mobiledevices.dmg.ghidra.GFileUtilityMethods;
    +import mobiledevices.dmg.reader.DmgFileReader;
    +
    +public class DmgServer {
    +
    +	private static void writeln(String s) {
    +
    +		StringBuilder encoded = new StringBuilder();
    +		char[] charArray = s.toCharArray();
    +		for (char c : charArray) {
    +			if (c == 11) {
    +				encoded.append(c);// tab
    +			}
    +
    +			if (c <= 31 || c == 127) {
    +				continue;// control characters
    +			}
    +
    +			encoded.append(c);
    +		}
    +
    +		System.out.println(encoded.toString());
    +	}
    +
    +	public static void sendResponse(String s) {
    +		System.out.println(s);
    +		System.out.flush();
    +	}
    +
    +	public static void sendResponses(String... responseStrs) {
    +		for (String s : responseStrs) {
    +			System.out.println(s);
    +		}
    +		System.out.flush();
    +	}
    +
    +	public static void log(String... logstrs) {
    +		for (String s : logstrs) {
    +			System.err.println(s);
    +		}
    +		System.err.flush();
    +	}
    +
    +	public static void main(String[] args) {
    +
    +		log("Waiting for client to connect to DMG server...");
    +
    +		BufferedReader inputReader = new BufferedReader(new InputStreamReader(System.in));
    +
    +		try {
    +			String openLine = inputReader.readLine();
    +			if (openLine == null) {
    +				return;
    +			}
    +			if (!openLine.startsWith("open ")) {
    +				return;//TODO handle invalid initial command???
    +			}
    +			String openPath = parseLine(openLine);
    +
    +			File openFile = new File(openPath);
    +			if (!openFile.exists()) {//TODO handle files that do not exist
    +
    +			}
    +
    +			try (GByteProvider provider = new GByteProvider(openFile);
    +					DmgFileReader dmgFileReader = new DmgFileReader(provider);) {
    +				dmgFileReader.open();
    +				while (true) {
    +					String line = inputReader.readLine();
    +					if (line == null) {
    +						break;
    +					}
    +					String[] parts = line.split(" ", 2);
    +					if (parts.length < 1)
    +						continue;
    +					String cmd = parts[0];
    +					switch (cmd) {
    +						case "close":
    +							log("Exiting DMG server process: close cmd");
    +							return;
    +						case "get_listing": {
    +							String path = parseLine(line);
    +							List<FSEntry> listing = dmgFileReader.getListing(path);
    +							sendResponse("" + listing.size());//write total number of children
    +							for (FSEntry childEntry : listing) {
    +								// send 3 responses: name, isfolder boolean, file length
    +								writeln(childEntry.getName());//write name of each child
    +								sendResponses("" + childEntry.isFolder(),
    +									"" + dmgFileReader.getLength(childEntry));
    +							}
    +						}
    +							break;
    +						case "get_info": {
    +							String path = parseLine(line);
    +							List<String> infoList = dmgFileReader.getInfo(path);
    +							sendResponse("" + infoList.size());//write total number of info lines
    +							for (String info : infoList) {
    +								sendResponse(info);//write each info line
    +							}
    +						}
    +							break;
    +						case "get_data": {
    +							String path = parseLine(line);
    +
    +							FSFile dmgFile = toFile(dmgFileReader, path);
    +
    +							if (dmgFile == null) {//TODO not a valid file...
    +								sendResponse("");
    +							}
    +							else {
    +								long expectedFileLength = dmgFileReader.getLength(dmgFile);
    +
    +								try (InputStream inputStream = dmgFileReader.getData(dmgFile)) {
    +									if (inputStream != null) {
    +										File temporaryFile =
    +											GFileUtilityMethods.writeTemporaryFile(inputStream);
    +
    +										sendResponse(temporaryFile.getAbsolutePath());
    +
    +										if (expectedFileLength != temporaryFile.length()) {
    +											log("file sizes do not match!");
    +										}
    +									}
    +									else {
    +										sendResponse("");// TODO: is this correct way to respond when error cond?
    +										log("No data stream for get_data for " + path);
    +									}
    +								}
    +							}
    +						}
    +							break;
    +					}
    +				}
    +			}
    +		}
    +		catch (IOException e) {
    +			log("IOException error in DMGServer command processing: " + e.getMessage());
    +			e.printStackTrace(System.err);
    +		}
    +		finally {
    +			log("DMG server has terminated.");
    +		}
    +	}
    +
    +	private static FSFile toFile(DmgFileReader dmgFileReader, String path) {
    +		FSEntry entry = dmgFileReader.getFileByPath(path);
    +
    +		if (entry == null) {
    +			//System.err.println("Bad path for toFile: " + path);
    +			return null;
    +		}
    +		if (entry.isFile()) {
    +			return entry.asFile();
    +		}
    +		else if (entry instanceof FSLink) {
    +			int limit = 0;
    +			while (limit++ < 10) {
    +				FSLink link = (FSLink) entry;
    +
    +				FSEntry linkTarget = link.getLinkTarget(
    +					dmgFileReader.convertPathToArrayAndStripFileSystemName(path));
    +
    +				if (linkTarget instanceof FSFile) {
    +					return linkTarget.asFile();
    +				}
    +				else if (linkTarget instanceof FSLink) {
    +					entry = linkTarget;
    +				}
    +				else {//anything else just return
    +					break;
    +				}
    +			}
    +		}
    +		return null;
    +	}
    +
    +	private static String parseLine(String openLine) {
    +		int space = openLine.indexOf(' ');
    +		String path = openLine.substring(space + 1).trim();
    +		return path;
    +	}
    +}
    
  • GPL/DMG/src/dmg/java/mobiledevices/dmg/xattr/XattrConstants.java+13 0 added
    @@ -0,0 +1,13 @@
    +/* ###
    + * IP: Public Domain
    + */
    +package mobiledevices.dmg.xattr;
    +
    +public final class XattrConstants {
    +
    +	public final static String      RESOURCE_XATTR_NAME  =  "com.apple.ResourceFork";
    +	public final static String       DECMPFS_XATTR_NAME  =  "com.apple.decmpfs";
    +	public final static String KAUTH_FILESEC_XATTR_NAME  =  "com.apple.system.Security";
    +	public final static String      KAUTH_SCOPE_PROCESS  =  "com.apple.kauth.process";
    +	
    +}
    
  • GPL/DMG/src/dmg/java/mobiledevices/dmg/zlib/ZLIB.java+120 0 added
    @@ -0,0 +1,120 @@
    +/* ###
    + * IP: Public Domain
    + */
    +package mobiledevices.dmg.zlib;
    +
    +import java.io.*;
    +import java.util.zip.*;
    +
    +/**
    + * 
    + * TODO make this more memory efficient!!
    + *
    + */
    +public class ZLIB {
    +	
    +    public ZLIB() {
    +	}
    +
    +	public ByteArrayOutputStream decompress( InputStream compressedIn, int expectedDecompressedLength ) throws IOException {
    +		return decompress( compressedIn, expectedDecompressedLength, false );
    +	}
    +
    +	public ByteArrayOutputStream decompress( InputStream compressedIn, int expectedDecompressedLength, boolean noWrap ) throws IOException {
    +
    +    	byte [] compressedBytes = convertInputStreamToByteArray( compressedIn );
    +
    +        ByteArrayOutputStream decompressedBOS = new ByteArrayOutputStream();
    +
    +    	byte [] tempDecompressedBytes = new byte[ 0x10000 ];
    +
    +    	int totalDecompressed = 0;
    +        int offset = 0;
    +
    +        try {
    +        	while ( offset < compressedBytes.length && totalDecompressed < expectedDecompressedLength ) {
    +
    +        		if ( !noWrap && compressedBytes [ offset ] != 0x78 ) {
    +        			break;
    +        		}
    +
    +                Inflater inflater = new Inflater( noWrap );
    +
    +                inflater.setInput( compressedBytes, offset, compressedBytes.length - offset );
    +
    +        		int nDecompressed = inflater.inflate( tempDecompressedBytes );
    +
    +        		if ( nDecompressed == 0 ) {
    +        			break;
    +        		}
    +
    +        		totalDecompressed += nDecompressed;
    +
    +        		decompressedBOS.write( tempDecompressedBytes, 0, nDecompressed );
    +
    +        		offset += inflater.getTotalIn();//increment total compressed bytes consumed
    +        	}
    +        }
    +        catch ( DataFormatException e ) {
    +        	throw new IOException( e.getMessage() );
    +        }
    +
    +        return decompressedBOS;
    +    }
    +
    +	public ByteArrayOutputStream compress(byte[] decompressedBytes) {
    +		return compress( false, decompressedBytes );
    +	}
    +
    +	public ByteArrayOutputStream compress(boolean noWrap, byte[] decompressedBytes) {
    +        ByteArrayOutputStream compressedBOS = new ByteArrayOutputStream();
    +
    +       	byte [] tempBuffer = new byte[ 0x10000 ];
    +
    +        int offset = 0;
    +
    +    	while ( offset < decompressedBytes.length ) {
    +
    +            Deflater deflater = new Deflater( 0, noWrap );
    +
    +           	deflater.setInput( decompressedBytes, offset, decompressedBytes.length - offset );
    +
    +           	deflater.finish();
    +
    +            if ( deflater.needsInput() ) {
    +            	System.err.println( "needs input??" );
    +            }
    +
    +            int nDeflated = deflater.deflate( tempBuffer );
    +
    +            if ( nDeflated == 0 ) {
    +            	break;
    +            }
    +
    +            compressedBOS.write( tempBuffer, 0, nDeflated );
    +
    +            offset += deflater.getTotalIn();
    +    	}
    +
    +        return compressedBOS;
    +	}
    +
    +	/**
    +	 * Converts the contents of an input stream to a byte array
    +	 * @param compressedIn
    +	 * @return
    +	 * @throws IOException
    +	 */
    +	private byte [] convertInputStreamToByteArray( InputStream compressedIn ) throws IOException {
    +		byte [] bytes = new byte[ 8096 ];
    +    	ByteArrayOutputStream compressedBOS = new ByteArrayOutputStream();
    +    	while ( true ) {
    +    		int nRead = compressedIn.read( bytes );
    +    		if ( nRead == -1 ) {
    +    			break;
    +    		}
    +    		compressedBOS.write( bytes, 0, nRead );
    +    	}
    +    	return compressedBOS.toByteArray();
    +	}
    +}
    
  • GPL/Icons/certification.manifest+31 0 added
  • GPL/Icons/ModifiedNuvola/closedDescendantsInView.svg+99 0 added
    @@ -0,0 +1,99 @@
    +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    +<!-- Created with Inkscape (http://www.inkscape.org/) -->
    +
    +<svg
    +   xmlns:svg="http://www.w3.org/2000/svg"
    +   xmlns="http://www.w3.org/2000/svg"
    +   xmlns:xlink="http://www.w3.org/1999/xlink"
    +   version="1.1"
    +   width="25"
    +   height="17"
    +   id="svg2">
    +  <defs
    +     id="defs4">
    +    <linearGradient
    +       x1="1.3965347"
    +       y1="2.8009901"
    +       x2="7.6133666"
    +       y2="6.9455447"
    +       id="linearGradient4260"
    +       xlink:href="#linearGradient4254"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="2.6579208"
    +       y1="2.260396"
    +       x2="6.6222773"
    +       y2="3.2934308"
    +       id="linearGradient4239"
    +       xlink:href="#linearGradient4233"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="9.6405945"
    +       y1="1.4495049"
    +       x2="5.4509902"
    +       y2="9.19802"
    +       id="linearGradient4228"
    +       xlink:href="#linearGradient4222"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       id="linearGradient4222">
    +      <stop
    +         id="stop4224"
    +         style="stop-color:#a38300;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4226"
    +         style="stop-color:#6c5600;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4233">
    +      <stop
    +         id="stop4235"
    +         style="stop-color:#32ac00;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4237"
    +         style="stop-color:#116200;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4254">
    +      <stop
    +         id="stop4256"
    +         style="stop-color:#166500;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4258"
    +         style="stop-color:#3a3000;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +  </defs>
    +  <g
    +     transform="translate(0,-1035.3622)"
    +     id="layer1">
    +    <image
    +       xlink:href="../nuvola/16x16/folder_yellow.png"
    +       x="1"
    +       y="1036.3622"
    +       width="16"
    +       height="16"
    +       id="image2998" />
    +    <g
    +       transform="translate(14.000269,1038.3624)"
    +       id="layer2">
    +      <path
    +         d="M 9.34375,0 C 9.331893,0.02007096 9.321443,0.04097223 9.3125,0.0625 9.291694,0.0611972 9.270806,0.0611972 9.25,0.0625 9.239262,0.0619942 9.229468,0.06294871 9.21875,0.0625 7.428818,-0.01243524 5.9102713,0.70487297 4.4375,1.40625 2.9559097,2.1118269 1.9397871,2.7910082 0.35734465,2.84375 -0.05907529,2.8522791 -0.26232937,3.5072089 0.07609465,3.75 2.0160738,5.1266314 3.5432986,6.2464747 5.59375,6.5 L 4.0625,9.25 C 3.9616756,9.4398454 4.0018376,9.6942052 4.15625,9.84375 l 1,1 C 5.3695576,11.057374 5.7807905,11.008026 5.9375,10.75 l 5,-9 C 11.038324,1.5601546 10.99816,1.3057948 10.84375,1.15625 l -1,-1 C 9.7346028,0.03783212 9.5657191,-0.02248351 9.40625,0 9.3854438,-0.0013028 9.3645562,-0.0013028 9.34375,0 z m -1.0625,1.1875 -2.5,4.25 C 4.3246653,5.2701854 2.8452361,4.5502621 1.3125,3.5625 2.5816669,3.2796931 3.7528393,2.8007738 4.84375,2.28125 6.0013234,1.7299795 7.1322792,1.3413489 8.28125,1.1875 z m 1.34375,0.125 0.25,0.25 -4.5,8.125 -0.25,-0.25 4.5,-8.125 z"
    +         id="path4241"
    +         style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:url(#linearGradient4260);fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans" />
    +      <path
    +         d="m 9.5,0.5 1,1 -5,9 -1,-1 5,-9 z"
    +         id="rect3709"
    +         style="fill:url(#linearGradient4228);fill-opacity:1;stroke:none" />
    +      <path
    +         d="M 0.50737752,3.3857784 C 3.9389568,3.2714061 5.9236512,0.39252559 9.2351487,0.54851491 L 6.0366336,6.0445543 C 3.9943893,5.9091062 2.5496218,4.8349783 0.50737752,3.3857784 z"
    +         id="rect4230"
    +         style="fill:url(#linearGradient4239);fill-opacity:1;stroke:none" />
    +    </g>
    +  </g>
    +</svg>
    
  • GPL/Icons/ModifiedNuvola/closedFolderArchive.svg+151 0 added
    @@ -0,0 +1,151 @@
    +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    +<!-- Created with Inkscape (http://www.inkscape.org/) -->
    +
    +<svg
    +   xmlns:svg="http://www.w3.org/2000/svg"
    +   xmlns="http://www.w3.org/2000/svg"
    +   xmlns:xlink="http://www.w3.org/1999/xlink"
    +   version="1.1"
    +   width="25"
    +   height="17"
    +   id="svg2">
    +  <defs
    +     id="defs4">
    +    <linearGradient
    +       x1="1.3965347"
    +       y1="2.8009901"
    +       x2="7.6133666"
    +       y2="6.9455447"
    +       id="linearGradient4260"
    +       xlink:href="#linearGradient4254"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="2.6579208"
    +       y1="2.260396"
    +       x2="6.6222773"
    +       y2="3.2934308"
    +       id="linearGradient4239"
    +       xlink:href="#linearGradient4233"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="9.6405945"
    +       y1="1.4495049"
    +       x2="5.4509902"
    +       y2="9.19802"
    +       id="linearGradient4228"
    +       xlink:href="#linearGradient4222"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       id="linearGradient4222">
    +      <stop
    +         id="stop4224"
    +         style="stop-color:#a38300;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4226"
    +         style="stop-color:#6c5600;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4233">
    +      <stop
    +         id="stop4235"
    +         style="stop-color:#32ac00;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4237"
    +         style="stop-color:#116200;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4254">
    +      <stop
    +         id="stop4256"
    +         style="stop-color:#166500;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4258"
    +         style="stop-color:#3a3000;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       x1="8.5"
    +       y1="11.630198"
    +       x2="2.567822"
    +       y2="0.54801965"
    +       id="linearGradient4886"
    +       xlink:href="#linearGradient4880"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="6.8984327"
    +       y1="7.0056653"
    +       x2="-0.66759026"
    +       y2="0.26749697"
    +       id="linearGradient4878"
    +       xlink:href="#linearGradient4872"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       id="linearGradient4872">
    +      <stop
    +         id="stop4874"
    +         style="stop-color:#009c31;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4876"
    +         style="stop-color:#009c31;stop-opacity:0.28498727"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4880">
    +      <stop
    +         id="stop4882"
    +         style="stop-color:#006331;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4884"
    +         style="stop-color:#006331;stop-opacity:0"
    +         offset="1" />
    +    </linearGradient>
    +  </defs>
    +  <g
    +     transform="translate(0,-1035.3622)"
    +     id="layer1">
    +    <image
    +       xlink:href="../nuvola/16x16/folder_yellow.png"
    +       x="1"
    +       y="1036.3622"
    +       width="16"
    +       height="16"
    +       id="image2998" />
    +    <g
    +       transform="translate(16,1036.3622)"
    +       id="layer1-8">
    +      <path
    +         d="M 3.5,-0.50000049 0.5,2.4999995 0.5,10.5 l 5,5 3,-3 0,-8.0000005 -5,-4.99999999 z"
    +         id="path4840"
    +         style="fill:#ffffff;fill-opacity:1;stroke:#004d00;stroke-linejoin:round;stroke-opacity:1" />
    +      <path
    +         d="M 5.7629584,2.9216062 13.995756,1.3810437 9.0560775,8.3053812 0.82327977,9.8459437 5.7629584,2.9216062 z"
    +         transform="matrix(0.60732696,0.79445199,0,1,0,0)"
    +         id="path4870"
    +         style="fill:#eaeaea;fill-opacity:1;stroke:none" />
    +      <path
    +         d="M 3.5,-0.49999991 8.5,4.5000002 8.5,12.5 3.5,7.5000001 3.5,-0.49999991 z"
    +         id="path4834"
    +         style="fill:#cecece;fill-opacity:1;stroke:none" />
    +      <path
    +         d="M 3.5,-0.49999991 0.5,2.5 l 0,8 3,-2.9999999 0,-8.00000001 z"
    +         id="path4836"
    +         style="fill:#9c9c9c;fill-opacity:1;stroke:none" />
    +      <path
    +         d="m 0.82327977,1.8459437 8.23279773,-1.54056247 0,7.99999997 -8.23279773,1.5405625 0,-8 z"
    +         transform="matrix(0.60732696,0.79445199,0,1,0,0)"
    +         id="rect4321"
    +         style="fill:url(#linearGradient4878);fill-opacity:1;stroke:none" />
    +      <path
    +         d="m 8.5,4.5000002 -3,2.9999999 0,7.9999999 3,-3 0,-7.9999998 z"
    +         id="path4838"
    +         style="fill:url(#linearGradient4886);fill-opacity:1;stroke:none" />
    +    </g>
    +  </g>
    +</svg>
    
  • GPL/Icons/ModifiedNuvola/closedFolderCheckedOut.svg+189 0 added
    @@ -0,0 +1,189 @@
    +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    +<!-- Created with Inkscape (http://www.inkscape.org/) -->
    +
    +<svg
    +   xmlns:svg="http://www.w3.org/2000/svg"
    +   xmlns="http://www.w3.org/2000/svg"
    +   xmlns:xlink="http://www.w3.org/1999/xlink"
    +   version="1.1"
    +   width="25"
    +   height="17"
    +   id="svg2">
    +  <defs
    +     id="defs4">
    +    <linearGradient
    +       x1="1.3965347"
    +       y1="2.8009901"
    +       x2="7.6133666"
    +       y2="6.9455447"
    +       id="linearGradient4260"
    +       xlink:href="#linearGradient4254"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="2.6579208"
    +       y1="2.260396"
    +       x2="6.6222773"
    +       y2="3.2934308"
    +       id="linearGradient4239"
    +       xlink:href="#linearGradient4233"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="9.6405945"
    +       y1="1.4495049"
    +       x2="5.4509902"
    +       y2="9.19802"
    +       id="linearGradient4228"
    +       xlink:href="#linearGradient4222"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       id="linearGradient4222">
    +      <stop
    +         id="stop4224"
    +         style="stop-color:#a38300;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4226"
    +         style="stop-color:#6c5600;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4233">
    +      <stop
    +         id="stop4235"
    +         style="stop-color:#32ac00;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4237"
    +         style="stop-color:#116200;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4254">
    +      <stop
    +         id="stop4256"
    +         style="stop-color:#166500;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4258"
    +         style="stop-color:#3a3000;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       x1="8.5"
    +       y1="11.630198"
    +       x2="2.567822"
    +       y2="0.54801965"
    +       id="linearGradient4886"
    +       xlink:href="#linearGradient4880"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="6.8984327"
    +       y1="7.0056653"
    +       x2="-0.66759026"
    +       y2="0.26749697"
    +       id="linearGradient4878"
    +       xlink:href="#linearGradient4872"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       id="linearGradient4872">
    +      <stop
    +         id="stop4874"
    +         style="stop-color:#009c31;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4876"
    +         style="stop-color:#009c31;stop-opacity:0.28498727"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4880">
    +      <stop
    +         id="stop4882"
    +         style="stop-color:#006331;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4884"
    +         style="stop-color:#006331;stop-opacity:0"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       x1="8.5"
    +       y1="11.630198"
    +       x2="2.567822"
    +       y2="0.54801965"
    +       id="linearGradient4886-0"
    +       xlink:href="#linearGradient4880-9"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="6.8984327"
    +       y1="7.0056653"
    +       x2="-0.66759026"
    +       y2="0.26749697"
    +       id="linearGradient4878-7"
    +       xlink:href="#linearGradient4872-0"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       id="linearGradient4872-0">
    +      <stop
    +         id="stop4874-0"
    +         style="stop-color:#f71000;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4876-2"
    +         style="stop-color:#f71000;stop-opacity:0.4427481"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4880-9">
    +      <stop
    +         id="stop4882-0"
    +         style="stop-color:#7d201b;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4884-8"
    +         style="stop-color:#bd3129;stop-opacity:0.22900763"
    +         offset="1" />
    +    </linearGradient>
    +  </defs>
    +  <g
    +     transform="translate(0,-1035.3622)"
    +     id="layer1">
    +    <image
    +       xlink:href="../nuvola/16x16/folder_yellow.png"
    +       x="1"
    +       y="1036.3622"
    +       width="16"
    +       height="16"
    +       id="image2998" />
    +    <g
    +       transform="translate(16,1036.3622)"
    +       id="layer1-7">
    +      <path
    +         d="M 3.5,-0.50000049 0.5,2.4999995 0.5,10.5 l 5,5 3,-3 0,-8.0000005 -5,-4.99999999 z"
    +         id="path4840"
    +         style="fill:#ffffff;fill-opacity:1;stroke:#4d0000;stroke-linejoin:round;stroke-opacity:1" />
    +      <path
    +         d="M 5.7629584,2.9216062 13.995756,1.3810437 9.0560775,8.3053812 0.82327977,9.8459437 5.7629584,2.9216062 z"
    +         transform="matrix(0.60732696,0.79445199,0,1,0,0)"
    +         id="path4870"
    +         style="fill:#eaeaea;fill-opacity:1;stroke:none" />
    +      <path
    +         d="M 3.5,-0.49999991 8.5,4.5000002 8.5,12.5 3.5,7.5000001 3.5,-0.49999991 z"
    +         id="path4834"
    +         style="fill:#cecece;fill-opacity:1;stroke:none" />
    +      <path
    +         d="M 3.5,-0.49999991 0.5,2.5 l 0,8 3,-2.9999999 0,-8.00000001 z"
    +         id="path4836"
    +         style="fill:#9c9c9c;fill-opacity:1;stroke:none" />
    +      <path
    +         d="m 8.5,4.5000002 -3,2.9999999 0,7.9999999 3,-3 0,-7.9999998 z"
    +         id="path4838"
    +         style="fill:url(#linearGradient4886-0);fill-opacity:1;stroke:none" />
    +      <path
    +         d="m 0.82327977,1.8459437 8.23279773,-1.54056247 0,7.99999997 -8.23279773,1.5405625 0,-8 z"
    +         transform="matrix(0.60732696,0.79445199,0,1,0,0)"
    +         id="rect4321"
    +         style="fill:url(#linearGradient4878-7);fill-opacity:1;stroke:none" />
    +    </g>
    +  </g>
    +</svg>
    
  • GPL/Icons/ModifiedNuvola/closedFolderClasses.svg+158 0 added
    @@ -0,0 +1,158 @@
    +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    +<!-- Created with Inkscape (http://www.inkscape.org/) -->
    +
    +<svg
    +   xmlns:svg="http://www.w3.org/2000/svg"
    +   xmlns="http://www.w3.org/2000/svg"
    +   xmlns:xlink="http://www.w3.org/1999/xlink"
    +   version="1.1"
    +   width="25"
    +   height="17"
    +   id="svg2">
    +  <defs
    +     id="defs4">
    +    <linearGradient
    +       x1="1.3965347"
    +       y1="2.8009901"
    +       x2="7.6133666"
    +       y2="6.9455447"
    +       id="linearGradient4260"
    +       xlink:href="#linearGradient4254"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="2.6579208"
    +       y1="2.260396"
    +       x2="6.6222773"
    +       y2="3.2934308"
    +       id="linearGradient4239"
    +       xlink:href="#linearGradient4233"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="9.6405945"
    +       y1="1.4495049"
    +       x2="5.4509902"
    +       y2="9.19802"
    +       id="linearGradient4228"
    +       xlink:href="#linearGradient4222"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       id="linearGradient4222">
    +      <stop
    +         id="stop4224"
    +         style="stop-color:#a38300;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4226"
    +         style="stop-color:#6c5600;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4233">
    +      <stop
    +         id="stop4235"
    +         style="stop-color:#32ac00;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4237"
    +         style="stop-color:#116200;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4254">
    +      <stop
    +         id="stop4256"
    +         style="stop-color:#166500;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4258"
    +         style="stop-color:#3a3000;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       x1="8.5"
    +       y1="11.630198"
    +       x2="2.567822"
    +       y2="0.54801965"
    +       id="linearGradient4886-0"
    +       xlink:href="#linearGradient4880-9"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="6.8984327"
    +       y1="7.0056653"
    +       x2="-0.66759026"
    +       y2="0.26749697"
    +       id="linearGradient4878-7"
    +       xlink:href="#linearGradient4872-0"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       id="linearGradient4872-0">
    +      <stop
    +         id="stop4874-0"
    +         style="stop-color:#f71000;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4876-2"
    +         style="stop-color:#f71000;stop-opacity:0.4427481"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4880-9">
    +      <stop
    +         id="stop4882-0"
    +         style="stop-color:#7d201b;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4884-8"
    +         style="stop-color:#bd3129;stop-opacity:0.22900763"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       x1="13"
    +       y1="13"
    +       x2="0"
    +       y2="0"
    +       id="linearGradient3598"
    +       xlink:href="#linearGradient3592"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       id="linearGradient3592">
    +      <stop
    +         id="stop3594"
    +         style="stop-color:#008000;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop3596"
    +         style="stop-color:#ffffff;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +  </defs>
    +  <g
    +     transform="translate(0,-1035.3622)"
    +     id="layer1">
    +    <image
    +       xlink:href="../nuvola/16x16/folder_yellow.png"
    +       x="1"
    +       y="1036.3622"
    +       width="16"
    +       height="16"
    +       id="image2998" />
    +    <g
    +       transform="translate(11,-1.99995)"
    +       id="layer1-5">
    +      <path
    +         d="m 15,7.5 a 7.5,7.5 0 1 1 -15,0 7.5,7.5 0 1 1 15,0 z"
    +         transform="matrix(0.8125,0,0,0.8125,0.40624999,1039.7684)"
    +         id="path2818"
    +         style="fill:url(#linearGradient3598);fill-opacity:1;stroke:#006a00;stroke-opacity:1" />
    +      <g
    +         transform="matrix(1.0062656,0,0,0.96251684,-0.04659213,39.20481)"
    +         id="text3600"
    +         style="font-size:9.615345px;font-style:normal;font-weight:normal;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans">
    +        <path
    +           d="m 8.9902632,1048.9746 c -0.3317856,0.1722 -0.6776497,0.3021 -1.0375934,0.3897 -0.3599545,0.088 -0.7355535,0.1315 -1.1267982,0.1315 -1.1674913,0 -2.092404,-0.3255 -2.7747407,-0.9766 -0.6823398,-0.6542 -1.0235089,-1.5399 -1.0235084,-2.6574 -5e-7,-1.1205 0.3411686,-2.0063 1.0235084,-2.6573 0.6823367,-0.6542 1.6072494,-0.9813 2.7747407,-0.9813 0.3912447,0 0.7668437,0.044 1.1267982,0.1315 0.3599437,0.088 0.7058078,0.2175 1.0375934,0.3897 l 0,1.4507 c -0.3349156,-0.2285 -0.6651298,-0.3959 -0.9906435,-0.5023 -0.3255246,-0.1065 -0.6682587,-0.1597 -1.0282034,-0.1597 -0.6447827,0 -1.1518414,0.2066 -1.5211776,0.6198 -0.3693419,0.4131 -0.5540115,0.9828 -0.5540091,1.7089 -2.4e-6,0.7231 0.1846672,1.2912 0.5540091,1.7043 0.3693362,0.4132 0.8763949,0.6198 1.5211776,0.6198 0.3599447,0 0.7026788,-0.053 1.0282034,-0.1597 0.3255137,-0.1064 0.6557279,-0.2738 0.9906435,-0.5023 l 0,1.4507"
    +           id="path3661"
    +           style="font-weight:bold;fill:#ffffff" />
    +      </g>
    +    </g>
    +  </g>
    +</svg>
    
  • GPL/Icons/ModifiedNuvola/closedFolderExternals.svg+201 0 added
    @@ -0,0 +1,201 @@
    +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    +<!-- Created with Inkscape (http://www.inkscape.org/) -->
    +
    +<svg
    +   xmlns:svg="http://www.w3.org/2000/svg"
    +   xmlns="http://www.w3.org/2000/svg"
    +   xmlns:xlink="http://www.w3.org/1999/xlink"
    +   version="1.1"
    +   width="25"
    +   height="17"
    +   id="svg2">
    +  <defs
    +     id="defs4">
    +    <linearGradient
    +       x1="1.3965347"
    +       y1="2.8009901"
    +       x2="7.6133666"
    +       y2="6.9455447"
    +       id="linearGradient4260"
    +       xlink:href="#linearGradient4254"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="2.6579208"
    +       y1="2.260396"
    +       x2="6.6222773"
    +       y2="3.2934308"
    +       id="linearGradient4239"
    +       xlink:href="#linearGradient4233"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="9.6405945"
    +       y1="1.4495049"
    +       x2="5.4509902"
    +       y2="9.19802"
    +       id="linearGradient4228"
    +       xlink:href="#linearGradient4222"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       id="linearGradient4222">
    +      <stop
    +         id="stop4224"
    +         style="stop-color:#a38300;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4226"
    +         style="stop-color:#6c5600;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4233">
    +      <stop
    +         id="stop4235"
    +         style="stop-color:#32ac00;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4237"
    +         style="stop-color:#116200;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4254">
    +      <stop
    +         id="stop4256"
    +         style="stop-color:#166500;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4258"
    +         style="stop-color:#3a3000;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       x1="13"
    +       y1="13"
    +       x2="0"
    +       y2="0"
    +       id="linearGradient3598"
    +       xlink:href="#linearGradient3592"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       id="linearGradient3592">
    +      <stop
    +         id="stop3594"
    +         style="stop-color:#008000;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop3596"
    +         style="stop-color:#ffffff;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       x1="3.2851486"
    +       y1="11.444585"
    +       x2="7.125"
    +       y2="15"
    +       id="linearGradient5517"
    +       xlink:href="#linearGradient5442"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="-1.8334223"
    +       y1="6.6957436"
    +       x2="7.8287196"
    +       y2="16.000019"
    +       id="linearGradient5509"
    +       xlink:href="#linearGradient5450"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="1.6893564"
    +       y1="5.3683167"
    +       x2="14.504462"
    +       y2="21.180693"
    +       id="linearGradient5456"
    +       xlink:href="#linearGradient5450"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(0.57338659,-17.647565)" />
    +    <linearGradient
    +       x1="2.7254951"
    +       y1="6.4945545"
    +       x2="13.09375"
    +       y2="16.765842"
    +       id="linearGradient5448"
    +       xlink:href="#linearGradient5442"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(0.57338659,-17.647565)" />
    +    <linearGradient
    +       id="linearGradient5442">
    +      <stop
    +         id="stop5444"
    +         style="stop-color:#3bb265;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop5446"
    +         style="stop-color:#246c32;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient5450">
    +      <stop
    +         id="stop5452"
    +         style="stop-color:#62dd90;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop5454"
    +         style="stop-color:#041308;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       x1="-1.8334223"
    +       y1="6.6957436"
    +       x2="7.8287196"
    +       y2="16.000019"
    +       id="linearGradient3368"
    +       xlink:href="#linearGradient5450"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="3.2851486"
    +       y1="11.444585"
    +       x2="7.125"
    +       y2="15"
    +       id="linearGradient3370"
    +       xlink:href="#linearGradient5442"
    +       gradientUnits="userSpaceOnUse" />
    +    <clipPath
    +       id="clipPath4146">
    +      <rect
    +         width="8"
    +         height="7"
    +         x="-0.0004619"
    +         y="9"
    +         id="rect4148"
    +         style="opacity:0.55979644;fill:#0060c0;fill-opacity:1;stroke:none" />
    +    </clipPath>
    +  </defs>
    +  <g
    +     transform="translate(0,-1035.3622)"
    +     id="layer1">
    +    <image
    +       xlink:href="../nuvola/16x16/folder_yellow.png"
    +       x="1"
    +       y="1036.3622"
    +       width="16"
    +       height="16"
    +       id="image2998" />
    +    <g
    +       transform="translate(22.426613,1043.041)"
    +       id="layer1-7">
    +      <g
    +         transform="translate(-6.4261511,-8.6788)"
    +         clip-path="url(#clipPath4146)"
    +         id="g3364">
    +        <path
    +           d="m 3.90625,8.28125 a 0.50005,0.50005 0 0 0 -0.34375,0.25 l -4,6.71875 A 0.50005,0.50005 0 0 0 0,16 l 8,0 a 0.50005,0.50005 0 0 0 0.4375,-0.75 l -4,-6.71875 a 0.50005,0.50005 0 0 0 -0.53125,-0.25 z"
    +           id="path5501"
    +           style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:url(#linearGradient3368);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans" />
    +        <path
    +           d="M 4,9.78125 7.125,15 0.875,15 4,9.78125 z"
    +           id="path5432"
    +           style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:url(#linearGradient3370);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans" />
    +      </g>
    +    </g>
    +  </g>
    +</svg>
    
  • GPL/Icons/ModifiedNuvola/closedFolderFunctions.svg+223 0 added
    @@ -0,0 +1,223 @@
    +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    +<!-- Created with Inkscape (http://www.inkscape.org/) -->
    +
    +<svg
    +   xmlns:svg="http://www.w3.org/2000/svg"
    +   xmlns="http://www.w3.org/2000/svg"
    +   xmlns:xlink="http://www.w3.org/1999/xlink"
    +   version="1.1"
    +   width="25"
    +   height="17"
    +   id="svg2">
    +  <defs
    +     id="defs4">
    +    <linearGradient
    +       x1="1.3965347"
    +       y1="2.8009901"
    +       x2="7.6133666"
    +       y2="6.9455447"
    +       id="linearGradient4260"
    +       xlink:href="#linearGradient4254"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="2.6579208"
    +       y1="2.260396"
    +       x2="6.6222773"
    +       y2="3.2934308"
    +       id="linearGradient4239"
    +       xlink:href="#linearGradient4233"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="9.6405945"
    +       y1="1.4495049"
    +       x2="5.4509902"
    +       y2="9.19802"
    +       id="linearGradient4228"
    +       xlink:href="#linearGradient4222"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       id="linearGradient4222">
    +      <stop
    +         id="stop4224"
    +         style="stop-color:#a38300;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4226"
    +         style="stop-color:#6c5600;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4233">
    +      <stop
    +         id="stop4235"
    +         style="stop-color:#32ac00;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4237"
    +         style="stop-color:#116200;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4254">
    +      <stop
    +         id="stop4256"
    +         style="stop-color:#166500;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4258"
    +         style="stop-color:#3a3000;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient5442">
    +      <stop
    +         id="stop5444"
    +         style="stop-color:#3bb265;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop5446"
    +         style="stop-color:#246c32;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient5450">
    +      <stop
    +         id="stop5452"
    +         style="stop-color:#62dd90;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop5454"
    +         style="stop-color:#041308;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       x1="-1.8334223"
    +       y1="6.6957436"
    +       x2="7.8287196"
    +       y2="16.000019"
    +       id="linearGradient3368"
    +       xlink:href="#linearGradient5450"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="3.2851486"
    +       y1="11.444585"
    +       x2="7.125"
    +       y2="15"
    +       id="linearGradient3370"
    +       xlink:href="#linearGradient5442"
    +       gradientUnits="userSpaceOnUse" />
    +    <clipPath
    +       id="clipPath4146">
    +      <rect
    +         width="8"
    +         height="7"
    +         x="-0.0004619"
    +         y="9"
    +         id="rect4148"
    +         style="opacity:0.55979644;fill:#0060c0;fill-opacity:1;stroke:none" />
    +    </clipPath>
    +    <linearGradient
    +       x1="4"
    +       y1="1045.5497"
    +       x2="-6.0625"
    +       y2="1026.2684"
    +       id="linearGradient3693"
    +       xlink:href="#linearGradient3613"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(2,2)" />
    +    <linearGradient
    +       x1="-5.095274"
    +       y1="1033.3518"
    +       x2="13.163674"
    +       y2="1058.4865"
    +       id="linearGradient3647"
    +       xlink:href="#linearGradient3639"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(1.96875,2)" />
    +    <linearGradient
    +       x1="-5.095274"
    +       y1="1033.3518"
    +       x2="13.163674"
    +       y2="1058.4865"
    +       id="linearGradient3633"
    +       xlink:href="#linearGradient3639"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-0.03124999,0)" />
    +    <linearGradient
    +       x1="4"
    +       y1="1045.5497"
    +       x2="-6.0625"
    +       y2="1026.2684"
    +       id="linearGradient3619"
    +       xlink:href="#linearGradient3613"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       id="linearGradient3613">
    +      <stop
    +         id="stop3615"
    +         style="stop-color:#ffffff;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop3617"
    +         style="stop-color:#000000;stop-opacity:0.72944295"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient3639">
    +      <stop
    +         id="stop3641"
    +         style="stop-color:#000000;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop3643"
    +         style="stop-color:#ffffff;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +  </defs>
    +  <g
    +     transform="translate(0,-1035.3622)"
    +     id="layer1">
    +    <image
    +       xlink:href="../nuvola/16x16/folder_yellow.png"
    +       x="1"
    +       y="1036.3622"
    +       width="16"
    +       height="16"
    +       id="image2998" />
    +    <g
    +       transform="translate(14,-2)"
    +       id="layer1-3">
    +      <rect
    +         width="7"
    +         height="10"
    +         x="2.5"
    +         y="1041.8622"
    +         id="rect3691"
    +         style="fill:url(#linearGradient3693);fill-opacity:1;stroke:none" />
    +      <path
    +         d="m 2,1041.3622 0,0.5 0,10 0,0.5 0.5,0 7,0 0.5,0 0,-0.5 0,-10 0,-0.5 -0.5,0 -7,0 -0.5,0 z m 1,1 6,0 0,9 -6,0 0,-9 z"
    +         id="path3645"
    +         style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:url(#linearGradient3647);fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans" />
    +      <rect
    +         width="7"
    +         height="10"
    +         x="0.5"
    +         y="1039.8622"
    +         id="rect2830"
    +         style="fill:url(#linearGradient3619);fill-opacity:1;stroke:none" />
    +      <g
    +         transform="matrix(0.95890403,0,0,1.0370725,0.10376718,1039.1783)"
    +         id="text3606"
    +         style="font-size:40px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans">
    +        <path
    +           d="m 5.1060718,5.9628425 0,-0.9642527 -1.0428572,0 C 4.0306249,3.7121191 4.083755,3.053575 4.7443307,3.0573877 5.1497912,3.0597279 4.9463843,3.3728736 5.1060718,4.034337 l 1.0428572,0 C 6.018572,3.997887 6.5367413,2.1133648 4.8909824,2.1058316 4.4999161,2.1040415 3.9247097,2.1079872 3.4880137,2.5817867 3.123014,2.9754047 3.1686383,3.7283135 3.0203573,4.9985898 l -1.0428572,0 0,0.9642527 1.0428572,0 C 2.9557912,7.3713527 2.9381392,7.5511525 2.6260642,7.7473342 2.4279358,7.871885 2.1534821,7.920488 1.9775001,7.891348 l 0,0.9642527 c 0.1433927,0.021865 0.2150895,-1.04e-5 0.3193751,-1.04e-5 C 2.8110412,8.8432983 3.2847948,8.6547561 3.5358927,8.3834973 4.040844,7.8380029 4.0632146,5.9628425 4.0632146,5.9628425"
    +           id="path3611"
    +           style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;fill:#ff0000;font-family:URW Chancery L;-inkscape-font-specification:URW Chancery L Bold Italic" />
    +      </g>
    +      <path
    +         d="m 0,1039.3622 0,0.5 0,10 0,0.5 0.5,0 7,0 0.5,0 0,-0.5 0,-10 0,-0.5 -0.5,0 -7,0 -0.5,0 z m 1,1 6,0 0,9 -6,0 0,-9 z"
    +         id="rect3621"
    +         style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:url(#linearGradient3633);fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans" />
    +    </g>
    +  </g>
    +</svg>
    
  • GPL/Icons/ModifiedNuvola/closedFolderGroup.svg+1144 0 added
    @@ -0,0 +1,1144 @@
    +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    +<!-- Created with Inkscape (http://www.inkscape.org/) -->
    +
    +<svg
    +   xmlns:svg="http://www.w3.org/2000/svg"
    +   xmlns="http://www.w3.org/2000/svg"
    +   xmlns:xlink="http://www.w3.org/1999/xlink"
    +   version="1.1"
    +   width="25"
    +   height="17"
    +   id="svg2">
    +  <defs
    +     id="defs4">
    +    <linearGradient
    +       x1="1.3965347"
    +       y1="2.8009901"
    +       x2="7.6133666"
    +       y2="6.9455447"
    +       id="linearGradient4260"
    +       xlink:href="#linearGradient4254"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="2.6579208"
    +       y1="2.260396"
    +       x2="6.6222773"
    +       y2="3.2934308"
    +       id="linearGradient4239"
    +       xlink:href="#linearGradient4233"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="9.6405945"
    +       y1="1.4495049"
    +       x2="5.4509902"
    +       y2="9.19802"
    +       id="linearGradient4228"
    +       xlink:href="#linearGradient4222"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       id="linearGradient4222">
    +      <stop
    +         id="stop4224"
    +         style="stop-color:#a38300;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4226"
    +         style="stop-color:#6c5600;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4233">
    +      <stop
    +         id="stop4235"
    +         style="stop-color:#32ac00;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4237"
    +         style="stop-color:#116200;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4254">
    +      <stop
    +         id="stop4256"
    +         style="stop-color:#166500;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4258"
    +         style="stop-color:#3a3000;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <clipPath
    +       id="clipPath4146">
    +      <rect
    +         width="8"
    +         height="7"
    +         x="-0.0004619"
    +         y="9"
    +         id="rect4148"
    +         style="opacity:0.55979644;fill:#0060c0;fill-opacity:1;stroke:none" />
    +    </clipPath>
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4777"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(0,2)" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4775"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-2,-1)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="12"
    +       y2="10"
    +       id="linearGradient4773"
    +       xlink:href="#linearGradient4310"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="12"
    +       y2="12"
    +       id="linearGradient4771"
    +       xlink:href="#linearGradient4328"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="6"
    +       y1="5"
    +       x2="10"
    +       y2="7"
    +       id="linearGradient4769"
    +       xlink:href="#linearGradient4302"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="6"
    +       x2="10"
    +       y2="9"
    +       id="linearGradient4767"
    +       xlink:href="#linearGradient4320"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="11"
    +       x2="4"
    +       y2="5"
    +       id="linearGradient4765"
    +       xlink:href="#linearGradient4294"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4763"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(4,0)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4761"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="5"
    +       x2="16"
    +       y2="9"
    +       id="linearGradient4759"
    +       xlink:href="#linearGradient4336"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10.0625"
    +       y1="8.03125"
    +       x2="12"
    +       y2="11"
    +       id="linearGradient4757"
    +       xlink:href="#linearGradient4344"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="16"
    +       y2="12"
    +       id="linearGradient4755"
    +       xlink:href="#linearGradient4366"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="16"
    +       y2="14"
    +       id="linearGradient4753"
    +       xlink:href="#linearGradient4382"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="4"
    +       y1="9"
    +       x2="10"
    +       y2="14"
    +       id="linearGradient4751"
    +       xlink:href="#linearGradient4374"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4707"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(0,2)" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4705"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-2,-1)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="12"
    +       y2="10"
    +       id="linearGradient4703"
    +       xlink:href="#linearGradient4310"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="12"
    +       y2="12"
    +       id="linearGradient4701"
    +       xlink:href="#linearGradient4328"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="6"
    +       y1="5"
    +       x2="10"
    +       y2="7"
    +       id="linearGradient4699"
    +       xlink:href="#linearGradient4302"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="6"
    +       x2="10"
    +       y2="9"
    +       id="linearGradient4697"
    +       xlink:href="#linearGradient4320"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="11"
    +       x2="4"
    +       y2="5"
    +       id="linearGradient4695"
    +       xlink:href="#linearGradient4294"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4693"
    +       xlink:href="#linearGradient3781"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(4,0)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4691"
    +       xlink:href="#linearGradient3769"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="5"
    +       x2="16"
    +       y2="9"
    +       id="linearGradient4689"
    +       xlink:href="#linearGradient3763"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10.0625"
    +       y1="8.03125"
    +       x2="12"
    +       y2="11"
    +       id="linearGradient4687"
    +       xlink:href="#linearGradient3775"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="16"
    +       y2="12"
    +       id="linearGradient4685"
    +       xlink:href="#linearGradient4366"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="16"
    +       y2="14"
    +       id="linearGradient4683"
    +       xlink:href="#linearGradient4382"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="4"
    +       y1="9"
    +       x2="10"
    +       y2="14"
    +       id="linearGradient4681"
    +       xlink:href="#linearGradient4374"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="4"
    +       y1="9"
    +       x2="10"
    +       y2="14"
    +       id="linearGradient4656"
    +       xlink:href="#linearGradient4374"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-3,-25)" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="16"
    +       y2="14"
    +       id="linearGradient4653"
    +       xlink:href="#linearGradient4382"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-3,-27)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="16"
    +       y2="12"
    +       id="linearGradient4650"
    +       xlink:href="#linearGradient4366"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-3,-27)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="16"
    +       y2="12"
    +       id="linearGradient4647"
    +       xlink:href="#linearGradient4366"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="16"
    +       y2="14"
    +       id="linearGradient4645"
    +       xlink:href="#linearGradient4382"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="4"
    +       y1="9"
    +       x2="10"
    +       y2="14"
    +       id="linearGradient4643"
    +       xlink:href="#linearGradient4374"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10.0625"
    +       y1="8.03125"
    +       x2="12"
    +       y2="11"
    +       id="linearGradient4641"
    +       xlink:href="#linearGradient4344"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-1,-28)" />
    +    <linearGradient
    +       x1="8"
    +       y1="5"
    +       x2="16"
    +       y2="9"
    +       id="linearGradient4638"
    +       xlink:href="#linearGradient4336"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-3,-27)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4634"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-1,-28)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4631"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(3,-28)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4628"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(4,0)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4626"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="5"
    +       x2="16"
    +       y2="9"
    +       id="linearGradient4624"
    +       xlink:href="#linearGradient4336"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10.0625"
    +       y1="8.03125"
    +       x2="12"
    +       y2="11"
    +       id="linearGradient4622"
    +       xlink:href="#linearGradient4344"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="11"
    +       x2="4"
    +       y2="5"
    +       id="linearGradient4620"
    +       xlink:href="#linearGradient4294"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-3,-27)" />
    +    <linearGradient
    +       x1="8"
    +       y1="6"
    +       x2="10"
    +       y2="9"
    +       id="linearGradient4617"
    +       xlink:href="#linearGradient4320"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-5,-28)" />
    +    <linearGradient
    +       x1="6"
    +       y1="5"
    +       x2="10"
    +       y2="7"
    +       id="linearGradient4614"
    +       xlink:href="#linearGradient4302"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-5,-28)" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="12"
    +       y2="12"
    +       id="linearGradient4611"
    +       xlink:href="#linearGradient4328"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-5,-28)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="12"
    +       y2="10"
    +       id="linearGradient4608"
    +       xlink:href="#linearGradient4310"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-5,-28)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="12"
    +       y2="10"
    +       id="linearGradient4605"
    +       xlink:href="#linearGradient4310"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="12"
    +       y2="12"
    +       id="linearGradient4603"
    +       xlink:href="#linearGradient4328"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="6"
    +       y1="5"
    +       x2="10"
    +       y2="7"
    +       id="linearGradient4601"
    +       xlink:href="#linearGradient4302"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="6"
    +       x2="10"
    +       y2="9"
    +       id="linearGradient4599"
    +       xlink:href="#linearGradient4320"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="11"
    +       x2="4"
    +       y2="5"
    +       id="linearGradient4597"
    +       xlink:href="#linearGradient4294"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4579"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-5,-28)" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4576"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-3,-25)" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4573"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(0,2)" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4571"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-2,-1)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="12"
    +       y2="10"
    +       id="linearGradient4569"
    +       xlink:href="#linearGradient4310"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="12"
    +       y2="12"
    +       id="linearGradient4567"
    +       xlink:href="#linearGradient4328"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="6"
    +       y1="5"
    +       x2="10"
    +       y2="7"
    +       id="linearGradient4565"
    +       xlink:href="#linearGradient4302"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="6"
    +       x2="10"
    +       y2="9"
    +       id="linearGradient4563"
    +       xlink:href="#linearGradient4320"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="11"
    +       x2="4"
    +       y2="5"
    +       id="linearGradient4561"
    +       xlink:href="#linearGradient4294"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4559"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(4,0)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4557"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="5"
    +       x2="16"
    +       y2="9"
    +       id="linearGradient4555"
    +       xlink:href="#linearGradient4336"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10.0625"
    +       y1="8.03125"
    +       x2="12"
    +       y2="11"
    +       id="linearGradient4553"
    +       xlink:href="#linearGradient4344"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="16"
    +       y2="12"
    +       id="linearGradient4551"
    +       xlink:href="#linearGradient4366"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="16"
    +       y2="14"
    +       id="linearGradient4549"
    +       xlink:href="#linearGradient4382"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="4"
    +       y1="9"
    +       x2="10"
    +       y2="14"
    +       id="linearGradient4547"
    +       xlink:href="#linearGradient4374"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4507"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(0,2)" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4505"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-2,-1)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="12"
    +       y2="10"
    +       id="linearGradient4503"
    +       xlink:href="#linearGradient4310"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="12"
    +       y2="12"
    +       id="linearGradient4501"
    +       xlink:href="#linearGradient4328"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="6"
    +       y1="5"
    +       x2="10"
    +       y2="7"
    +       id="linearGradient4499"
    +       xlink:href="#linearGradient4302"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="6"
    +       x2="10"
    +       y2="9"
    +       id="linearGradient4497"
    +       xlink:href="#linearGradient4320"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="11"
    +       x2="4"
    +       y2="5"
    +       id="linearGradient4495"
    +       xlink:href="#linearGradient4294"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4493"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(4,0)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4491"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="5"
    +       x2="16"
    +       y2="9"
    +       id="linearGradient4489"
    +       xlink:href="#linearGradient4336"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10.0625"
    +       y1="8.03125"
    +       x2="12"
    +       y2="11"
    +       id="linearGradient4487"
    +       xlink:href="#linearGradient4344"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="16"
    +       y2="12"
    +       id="linearGradient4485"
    +       xlink:href="#linearGradient4366"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="16"
    +       y2="14"
    +       id="linearGradient4483"
    +       xlink:href="#linearGradient4382"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="4"
    +       y1="9"
    +       x2="10"
    +       y2="14"
    +       id="linearGradient4481"
    +       xlink:href="#linearGradient4374"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4438"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(0,2)" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4415"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-2,-1)" />
    +    <linearGradient
    +       id="linearGradient4392-6">
    +      <stop
    +         id="stop4394-2"
    +         style="stop-color:#000000;stop-opacity:0.17195767"
    +         offset="0" />
    +      <stop
    +         id="stop4396-8"
    +         style="stop-color:#000000;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4390-0"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="16"
    +       y2="14"
    +       id="linearGradient4380"
    +       xlink:href="#linearGradient4382"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="4"
    +       y1="9"
    +       x2="10"
    +       y2="14"
    +       id="linearGradient4372"
    +       xlink:href="#linearGradient4374"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="16"
    +       y2="12"
    +       id="linearGradient4364"
    +       xlink:href="#linearGradient4366"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4362"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(4,0)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4352"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10.0625"
    +       y1="8.03125"
    +       x2="12"
    +       y2="11"
    +       id="linearGradient4350"
    +       xlink:href="#linearGradient4344"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="5"
    +       x2="16"
    +       y2="9"
    +       id="linearGradient4342"
    +       xlink:href="#linearGradient4336"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="12"
    +       y2="12"
    +       id="linearGradient4326"
    +       xlink:href="#linearGradient4328"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="6"
    +       x2="10"
    +       y2="9"
    +       id="linearGradient4318"
    +       xlink:href="#linearGradient4320"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="12"
    +       y2="10"
    +       id="linearGradient4316"
    +       xlink:href="#linearGradient4310"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="6"
    +       y1="5"
    +       x2="10"
    +       y2="7"
    +       id="linearGradient4308"
    +       xlink:href="#linearGradient4302"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="11"
    +       x2="4"
    +       y2="5"
    +       id="linearGradient4300"
    +       xlink:href="#linearGradient4294"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       id="linearGradient4294">
    +      <stop
    +         id="stop4296"
    +         style="stop-color:#008e00;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4298"
    +         style="stop-color:#00d300;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4302">
    +      <stop
    +         id="stop4304"
    +         style="stop-color:#0fff00;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4306"
    +         style="stop-color:#0fba00;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4310">
    +      <stop
    +         id="stop4312"
    +         style="stop-color:#19ff00;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4314"
    +         style="stop-color:#19a800;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4320">
    +      <stop
    +         id="stop4322"
    +         style="stop-color:#0f8400;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4324"
    +         style="stop-color:#0fba00;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4328">
    +      <stop
    +         id="stop4330"
    +         style="stop-color:#197600;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4332"
    +         style="stop-color:#19a800;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4336">
    +      <stop
    +         id="stop4338"
    +         style="stop-color:#ffff00;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4340"
    +         style="stop-color:#b7b400;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4344">
    +      <stop
    +         id="stop4346"
    +         style="stop-color:#929100;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4348"
    +         style="stop-color:#c4c400;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4354">
    +      <stop
    +         id="stop4356"
    +         style="stop-color:#616000;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4358"
    +         style="stop-color:#bfbf00;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4366">
    +      <stop
    +         id="stop4368"
    +         style="stop-color:#ff0000;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4370"
    +         style="stop-color:#630000;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4374">
    +      <stop
    +         id="stop4376"
    +         style="stop-color:#dc0000;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4378"
    +         style="stop-color:#9a0000;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4382">
    +      <stop
    +         id="stop4384"
    +         style="stop-color:#370000;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4386"
    +         style="stop-color:#ff0000;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient3763">
    +      <stop
    +         id="stop3765"
    +         style="stop-color:#0080ff;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop3767"
    +         style="stop-color:#005bb6;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient3769">
    +      <stop
    +         id="stop3771"
    +         style="stop-color:#003060;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop3773"
    +         style="stop-color:#0060c0;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient3775">
    +      <stop
    +         id="stop3777"
    +         style="stop-color:#004992;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop3779"
    +         style="stop-color:#0062c4;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient3781">
    +      <stop
    +         id="stop3783"
    +         style="stop-color:#003060;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop3785"
    +         style="stop-color:#0060c0;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       x1="5"
    +       y1="2"
    +       x2="5"
    +       y2="7.9107141"
    +       id="linearGradient4266"
    +       xlink:href="#linearGradient4260-0"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="5"
    +       y1="7.0178576"
    +       x2="5"
    +       y2="0.03571428"
    +       id="linearGradient4258"
    +       xlink:href="#linearGradient4252"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       id="linearGradient4252">
    +      <stop
    +         id="stop4254"
    +         style="stop-color:#7e593a;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4256-5"
    +         style="stop-color:#7e593a;stop-opacity:0"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4260-0">
    +      <stop
    +         id="stop4262"
    +         style="stop-color:#60442c;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4264"
    +         style="stop-color:#60442c;stop-opacity:0"
    +         offset="1" />
    +    </linearGradient>
    +  </defs>
    +  <g
    +     transform="translate(0,-1035.3622)"
    +     id="layer1">
    +    <image
    +       xlink:href="../nuvola/16x16/folder_yellow.png"
    +       x="1"
    +       y="1036.3622"
    +       width="16"
    +       height="16"
    +       id="image2998" />
    +    <g
    +       transform="translate(14,-5)"
    +       id="layer1-3">
    +      <rect
    +         width="5.0131011"
    +         height="4.0131016"
    +         ry="1.5066092"
    +         x="2.4934494"
    +         y="1044.8556"
    +         id="rect4270"
    +         style="fill:none;stroke:#372915;stroke-width:0.9868986;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
    +      <path
    +         d="M 0,2 0,4 1,4 1,8 9,8 9,4 10,4 10,2 0,2 z"
    +         transform="translate(0,1044.3622)"
    +         id="path4272"
    +         style="fill:#ffffff;fill-opacity:1;stroke:none" />
    +      <path
    +         d="M 0,2 0,4 1,4 1,8 9,8 9,4 10,4 10,2 0,2 z"
    +         transform="translate(0,1044.3622)"
    +         id="rect3719"
    +         style="fill:url(#linearGradient4258);fill-opacity:1;stroke:none" />
    +      <path
    +         d="M 0,2 0,4 1,4 1,3 9,3 9,4 10,4 10,2 0,2 z"
    +         transform="translate(0,1044.3622)"
    +         id="rect4242"
    +         style="fill:url(#linearGradient4266);fill-opacity:1;stroke:none" />
    +      <path
    +         d="m 9.0000003,1052.3622 0,-4 -1,0 0,3 -6.0000003,0 0,-3 -1,0 0,4 8.0000003,0 z"
    +         id="path4250"
    +         style="fill:#60442c;fill-opacity:0.63660476;stroke:none" />
    +    </g>
    +  </g>
    +</svg>
    
  • GPL/Icons/ModifiedNuvola/closedFolderInvalid.svg+1193 0 added
    @@ -0,0 +1,1193 @@
    +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    +<!-- Created with Inkscape (http://www.inkscape.org/) -->
    +
    +<svg
    +   xmlns:svg="http://www.w3.org/2000/svg"
    +   xmlns="http://www.w3.org/2000/svg"
    +   xmlns:xlink="http://www.w3.org/1999/xlink"
    +   version="1.1"
    +   width="25"
    +   height="17"
    +   id="svg2">
    +  <defs
    +     id="defs4">
    +    <linearGradient
    +       x1="1.3965347"
    +       y1="2.8009901"
    +       x2="7.6133666"
    +       y2="6.9455447"
    +       id="linearGradient4260"
    +       xlink:href="#linearGradient4254"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="2.6579208"
    +       y1="2.260396"
    +       x2="6.6222773"
    +       y2="3.2934308"
    +       id="linearGradient4239"
    +       xlink:href="#linearGradient4233"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="9.6405945"
    +       y1="1.4495049"
    +       x2="5.4509902"
    +       y2="9.19802"
    +       id="linearGradient4228"
    +       xlink:href="#linearGradient4222"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       id="linearGradient4222">
    +      <stop
    +         id="stop4224"
    +         style="stop-color:#a38300;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4226"
    +         style="stop-color:#6c5600;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4233">
    +      <stop
    +         id="stop4235"
    +         style="stop-color:#32ac00;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4237"
    +         style="stop-color:#116200;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4254">
    +      <stop
    +         id="stop4256"
    +         style="stop-color:#166500;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4258"
    +         style="stop-color:#3a3000;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <clipPath
    +       id="clipPath4146">
    +      <rect
    +         width="8"
    +         height="7"
    +         x="-0.0004619"
    +         y="9"
    +         id="rect4148"
    +         style="opacity:0.55979644;fill:#0060c0;fill-opacity:1;stroke:none" />
    +    </clipPath>
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4777"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(0,2)" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4775"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-2,-1)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="12"
    +       y2="10"
    +       id="linearGradient4773"
    +       xlink:href="#linearGradient4310"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="12"
    +       y2="12"
    +       id="linearGradient4771"
    +       xlink:href="#linearGradient4328"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="6"
    +       y1="5"
    +       x2="10"
    +       y2="7"
    +       id="linearGradient4769"
    +       xlink:href="#linearGradient4302"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="6"
    +       x2="10"
    +       y2="9"
    +       id="linearGradient4767"
    +       xlink:href="#linearGradient4320"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="11"
    +       x2="4"
    +       y2="5"
    +       id="linearGradient4765"
    +       xlink:href="#linearGradient4294"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4763"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(4,0)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4761"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="5"
    +       x2="16"
    +       y2="9"
    +       id="linearGradient4759"
    +       xlink:href="#linearGradient4336"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10.0625"
    +       y1="8.03125"
    +       x2="12"
    +       y2="11"
    +       id="linearGradient4757"
    +       xlink:href="#linearGradient4344"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="16"
    +       y2="12"
    +       id="linearGradient4755"
    +       xlink:href="#linearGradient4366"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="16"
    +       y2="14"
    +       id="linearGradient4753"
    +       xlink:href="#linearGradient4382"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="4"
    +       y1="9"
    +       x2="10"
    +       y2="14"
    +       id="linearGradient4751"
    +       xlink:href="#linearGradient4374"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4707"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(0,2)" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4705"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-2,-1)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="12"
    +       y2="10"
    +       id="linearGradient4703"
    +       xlink:href="#linearGradient4310"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="12"
    +       y2="12"
    +       id="linearGradient4701"
    +       xlink:href="#linearGradient4328"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="6"
    +       y1="5"
    +       x2="10"
    +       y2="7"
    +       id="linearGradient4699"
    +       xlink:href="#linearGradient4302"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="6"
    +       x2="10"
    +       y2="9"
    +       id="linearGradient4697"
    +       xlink:href="#linearGradient4320"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="11"
    +       x2="4"
    +       y2="5"
    +       id="linearGradient4695"
    +       xlink:href="#linearGradient4294"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4693"
    +       xlink:href="#linearGradient3781"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(4,0)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4691"
    +       xlink:href="#linearGradient3769"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="5"
    +       x2="16"
    +       y2="9"
    +       id="linearGradient4689"
    +       xlink:href="#linearGradient3763"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10.0625"
    +       y1="8.03125"
    +       x2="12"
    +       y2="11"
    +       id="linearGradient4687"
    +       xlink:href="#linearGradient3775"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="16"
    +       y2="12"
    +       id="linearGradient4685"
    +       xlink:href="#linearGradient4366"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="16"
    +       y2="14"
    +       id="linearGradient4683"
    +       xlink:href="#linearGradient4382"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="4"
    +       y1="9"
    +       x2="10"
    +       y2="14"
    +       id="linearGradient4681"
    +       xlink:href="#linearGradient4374"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="4"
    +       y1="9"
    +       x2="10"
    +       y2="14"
    +       id="linearGradient4656"
    +       xlink:href="#linearGradient4374"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-3,-25)" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="16"
    +       y2="14"
    +       id="linearGradient4653"
    +       xlink:href="#linearGradient4382"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-3,-27)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="16"
    +       y2="12"
    +       id="linearGradient4650"
    +       xlink:href="#linearGradient4366"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-3,-27)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="16"
    +       y2="12"
    +       id="linearGradient4647"
    +       xlink:href="#linearGradient4366"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="16"
    +       y2="14"
    +       id="linearGradient4645"
    +       xlink:href="#linearGradient4382"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="4"
    +       y1="9"
    +       x2="10"
    +       y2="14"
    +       id="linearGradient4643"
    +       xlink:href="#linearGradient4374"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10.0625"
    +       y1="8.03125"
    +       x2="12"
    +       y2="11"
    +       id="linearGradient4641"
    +       xlink:href="#linearGradient4344"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-1,-28)" />
    +    <linearGradient
    +       x1="8"
    +       y1="5"
    +       x2="16"
    +       y2="9"
    +       id="linearGradient4638"
    +       xlink:href="#linearGradient4336"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-3,-27)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4634"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-1,-28)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4631"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(3,-28)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4628"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(4,0)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4626"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="5"
    +       x2="16"
    +       y2="9"
    +       id="linearGradient4624"
    +       xlink:href="#linearGradient4336"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10.0625"
    +       y1="8.03125"
    +       x2="12"
    +       y2="11"
    +       id="linearGradient4622"
    +       xlink:href="#linearGradient4344"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="11"
    +       x2="4"
    +       y2="5"
    +       id="linearGradient4620"
    +       xlink:href="#linearGradient4294"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-3,-27)" />
    +    <linearGradient
    +       x1="8"
    +       y1="6"
    +       x2="10"
    +       y2="9"
    +       id="linearGradient4617"
    +       xlink:href="#linearGradient4320"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-5,-28)" />
    +    <linearGradient
    +       x1="6"
    +       y1="5"
    +       x2="10"
    +       y2="7"
    +       id="linearGradient4614"
    +       xlink:href="#linearGradient4302"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-5,-28)" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="12"
    +       y2="12"
    +       id="linearGradient4611"
    +       xlink:href="#linearGradient4328"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-5,-28)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="12"
    +       y2="10"
    +       id="linearGradient4608"
    +       xlink:href="#linearGradient4310"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-5,-28)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="12"
    +       y2="10"
    +       id="linearGradient4605"
    +       xlink:href="#linearGradient4310"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="12"
    +       y2="12"
    +       id="linearGradient4603"
    +       xlink:href="#linearGradient4328"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="6"
    +       y1="5"
    +       x2="10"
    +       y2="7"
    +       id="linearGradient4601"
    +       xlink:href="#linearGradient4302"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="6"
    +       x2="10"
    +       y2="9"
    +       id="linearGradient4599"
    +       xlink:href="#linearGradient4320"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="11"
    +       x2="4"
    +       y2="5"
    +       id="linearGradient4597"
    +       xlink:href="#linearGradient4294"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4579"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-5,-28)" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4576"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-3,-25)" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4573"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(0,2)" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4571"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-2,-1)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="12"
    +       y2="10"
    +       id="linearGradient4569"
    +       xlink:href="#linearGradient4310"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="12"
    +       y2="12"
    +       id="linearGradient4567"
    +       xlink:href="#linearGradient4328"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="6"
    +       y1="5"
    +       x2="10"
    +       y2="7"
    +       id="linearGradient4565"
    +       xlink:href="#linearGradient4302"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="6"
    +       x2="10"
    +       y2="9"
    +       id="linearGradient4563"
    +       xlink:href="#linearGradient4320"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="11"
    +       x2="4"
    +       y2="5"
    +       id="linearGradient4561"
    +       xlink:href="#linearGradient4294"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4559"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(4,0)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4557"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="5"
    +       x2="16"
    +       y2="9"
    +       id="linearGradient4555"
    +       xlink:href="#linearGradient4336"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10.0625"
    +       y1="8.03125"
    +       x2="12"
    +       y2="11"
    +       id="linearGradient4553"
    +       xlink:href="#linearGradient4344"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="16"
    +       y2="12"
    +       id="linearGradient4551"
    +       xlink:href="#linearGradient4366"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="16"
    +       y2="14"
    +       id="linearGradient4549"
    +       xlink:href="#linearGradient4382"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="4"
    +       y1="9"
    +       x2="10"
    +       y2="14"
    +       id="linearGradient4547"
    +       xlink:href="#linearGradient4374"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4507"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(0,2)" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4505"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-2,-1)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="12"
    +       y2="10"
    +       id="linearGradient4503"
    +       xlink:href="#linearGradient4310"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="12"
    +       y2="12"
    +       id="linearGradient4501"
    +       xlink:href="#linearGradient4328"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="6"
    +       y1="5"
    +       x2="10"
    +       y2="7"
    +       id="linearGradient4499"
    +       xlink:href="#linearGradient4302"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="6"
    +       x2="10"
    +       y2="9"
    +       id="linearGradient4497"
    +       xlink:href="#linearGradient4320"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="11"
    +       x2="4"
    +       y2="5"
    +       id="linearGradient4495"
    +       xlink:href="#linearGradient4294"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4493"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(4,0)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4491"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="5"
    +       x2="16"
    +       y2="9"
    +       id="linearGradient4489"
    +       xlink:href="#linearGradient4336"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10.0625"
    +       y1="8.03125"
    +       x2="12"
    +       y2="11"
    +       id="linearGradient4487"
    +       xlink:href="#linearGradient4344"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="16"
    +       y2="12"
    +       id="linearGradient4485"
    +       xlink:href="#linearGradient4366"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="16"
    +       y2="14"
    +       id="linearGradient4483"
    +       xlink:href="#linearGradient4382"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="4"
    +       y1="9"
    +       x2="10"
    +       y2="14"
    +       id="linearGradient4481"
    +       xlink:href="#linearGradient4374"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4438"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(0,2)" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4415"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-2,-1)" />
    +    <linearGradient
    +       id="linearGradient4392-6">
    +      <stop
    +         id="stop4394-2"
    +         style="stop-color:#000000;stop-opacity:0.17195767"
    +         offset="0" />
    +      <stop
    +         id="stop4396-8"
    +         style="stop-color:#000000;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4390-0"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="16"
    +       y2="14"
    +       id="linearGradient4380"
    +       xlink:href="#linearGradient4382"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="4"
    +       y1="9"
    +       x2="10"
    +       y2="14"
    +       id="linearGradient4372"
    +       xlink:href="#linearGradient4374"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="16"
    +       y2="12"
    +       id="linearGradient4364"
    +       xlink:href="#linearGradient4366"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4362"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(4,0)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4352"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10.0625"
    +       y1="8.03125"
    +       x2="12"
    +       y2="11"
    +       id="linearGradient4350"
    +       xlink:href="#linearGradient4344"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="5"
    +       x2="16"
    +       y2="9"
    +       id="linearGradient4342"
    +       xlink:href="#linearGradient4336"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="12"
    +       y2="12"
    +       id="linearGradient4326"
    +       xlink:href="#linearGradient4328"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="6"
    +       x2="10"
    +       y2="9"
    +       id="linearGradient4318"
    +       xlink:href="#linearGradient4320"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="12"
    +       y2="10"
    +       id="linearGradient4316"
    +       xlink:href="#linearGradient4310"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="6"
    +       y1="5"
    +       x2="10"
    +       y2="7"
    +       id="linearGradient4308"
    +       xlink:href="#linearGradient4302"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="11"
    +       x2="4"
    +       y2="5"
    +       id="linearGradient4300"
    +       xlink:href="#linearGradient4294"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       id="linearGradient4294">
    +      <stop
    +         id="stop4296"
    +         style="stop-color:#008e00;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4298"
    +         style="stop-color:#00d300;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4302">
    +      <stop
    +         id="stop4304"
    +         style="stop-color:#0fff00;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4306"
    +         style="stop-color:#0fba00;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4310">
    +      <stop
    +         id="stop4312"
    +         style="stop-color:#19ff00;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4314"
    +         style="stop-color:#19a800;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4320">
    +      <stop
    +         id="stop4322"
    +         style="stop-color:#0f8400;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4324"
    +         style="stop-color:#0fba00;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4328">
    +      <stop
    +         id="stop4330"
    +         style="stop-color:#197600;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4332"
    +         style="stop-color:#19a800;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4336">
    +      <stop
    +         id="stop4338"
    +         style="stop-color:#ffff00;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4340"
    +         style="stop-color:#b7b400;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4344">
    +      <stop
    +         id="stop4346"
    +         style="stop-color:#929100;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4348"
    +         style="stop-color:#c4c400;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4354">
    +      <stop
    +         id="stop4356"
    +         style="stop-color:#616000;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4358"
    +         style="stop-color:#bfbf00;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4366">
    +      <stop
    +         id="stop4368"
    +         style="stop-color:#ff0000;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4370"
    +         style="stop-color:#630000;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4374">
    +      <stop
    +         id="stop4376"
    +         style="stop-color:#dc0000;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4378"
    +         style="stop-color:#9a0000;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4382">
    +      <stop
    +         id="stop4384"
    +         style="stop-color:#370000;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4386"
    +         style="stop-color:#ff0000;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient3763">
    +      <stop
    +         id="stop3765"
    +         style="stop-color:#0080ff;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop3767"
    +         style="stop-color:#005bb6;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient3769">
    +      <stop
    +         id="stop3771"
    +         style="stop-color:#003060;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop3773"
    +         style="stop-color:#0060c0;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient3775">
    +      <stop
    +         id="stop3777"
    +         style="stop-color:#004992;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop3779"
    +         style="stop-color:#0062c4;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient3781">
    +      <stop
    +         id="stop3783"
    +         style="stop-color:#003060;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop3785"
    +         style="stop-color:#0060c0;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       x1="8.5"
    +       y1="11.630198"
    +       x2="2.567822"
    +       y2="0.54801965"
    +       id="linearGradient4886"
    +       xlink:href="#linearGradient4880"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="6.8984327"
    +       y1="7.0056653"
    +       x2="-0.66759026"
    +       y2="0.26749697"
    +       id="linearGradient4878"
    +       xlink:href="#linearGradient4872"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       id="linearGradient4872">
    +      <stop
    +         id="stop4874"
    +         style="stop-color:#000000;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4876"
    +         style="stop-color:#000000;stop-opacity:0.47079039"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4880">
    +      <stop
    +         id="stop4882"
    +         style="stop-color:#000000;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4884"
    +         style="stop-color:#000000;stop-opacity:0.55326462"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       x1="17.229385"
    +       y1="1060.4314"
    +       x2="-0.53286755"
    +       y2="1035.2596"
    +       id="linearGradient4193"
    +       xlink:href="#linearGradient4187"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="13.55006"
    +       y1="1056.4983"
    +       x2="-1.7001013"
    +       y2="1032.4685"
    +       id="linearGradient4185"
    +       xlink:href="#linearGradient4179"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       id="linearGradient4179">
    +      <stop
    +         id="stop4181"
    +         style="stop-color:#640000;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4183"
    +         style="stop-color:#ce0000;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4187">
    +      <stop
    +         id="stop4189"
    +         style="stop-color:#990000;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4191"
    +         style="stop-color:#fe0000;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +  </defs>
    +  <g
    +     transform="translate(0,-1035.3622)"
    +     id="layer1">
    +    <image
    +       xlink:href="../nuvola/16x16/folder_yellow.png"
    +       x="1"
    +       y="1036.3622"
    +       width="16"
    +       height="16"
    +       id="image2998" />
    +    <g
    +       transform="translate(16,1036.3622)"
    +       id="layer1-2">
    +      <path
    +         d="M 3.5,-0.50000049 0.5,2.4999995 0.5,10.5 l 5,5 3,-3 0,-8.0000005 -5,-4.99999999 z"
    +         id="path4840"
    +         style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-linejoin:round;stroke-opacity:1" />
    +      <path
    +         d="M 5.7629584,2.9216062 13.995756,1.3810437 9.0560775,8.3053812 0.82327977,9.8459437 5.7629584,2.9216062 z"
    +         transform="matrix(0.60732696,0.79445199,0,1,0,0)"
    +         id="path4870"
    +         style="fill:#eaeaea;fill-opacity:1;stroke:none" />
    +      <path
    +         d="M 3.5,-0.49999991 8.5,4.5000002 8.5,12.5 3.5,7.5000001 3.5,-0.49999991 z"
    +         id="path4834"
    +         style="fill:#cecece;fill-opacity:1;stroke:none" />
    +      <path
    +         d="M 3.5,-0.49999991 0.5,2.5 l 0,8 3,-2.9999999 0,-8.00000001 z"
    +         id="path4836"
    +         style="fill:#9c9c9c;fill-opacity:1;stroke:none" />
    +      <path
    +         d="m 8.5,4.5000002 -3,2.9999999 0,7.9999999 3,-3 0,-7.9999998 z"
    +         id="path4838"
    +         style="fill:url(#linearGradient4886);fill-opacity:1;stroke:none" />
    +      <path
    +         d="m 0.82327977,1.8459437 8.23279773,-1.54056247 0,7.99999997 -8.23279773,1.5405625 0,-8 z"
    +         transform="matrix(0.60732696,0.79445199,0,1,0,0)"
    +         id="rect4321"
    +         style="fill:url(#linearGradient4878);fill-opacity:1;stroke:none" />
    +    </g>
    +    <g
    +       transform="matrix(0.99990126,0,0,1.0020366,5.0007302,-3.125506)"
    +       id="layer1-1">
    +      <path
    +         d="m 2.5502525,1039.9125 c -2.72769796,2.7277 -2.72278534,7.1767 0,9.8994 2.7228561,2.7229 7.171797,2.7277 9.8994945,0 2.727698,-2.7277 2.722857,-7.1766 0,-9.8994 -2.7227849,-2.7228 -7.1717968,-2.7277 -9.8994945,0 z m 0.7733981,2.2318 c 0.011068,-0.017 0.032904,-0.028 0.044194,-0.044 l 6.9163884,6.9164 c -1.9425749,1.3209 -4.5899139,1.1111 -6.319767,-0.6188 -1.7147781,-1.7147 -1.9239757,-4.3157 -0.6408155,-6.2534 z m 1.4142135,-1.4143 c 1.940179,-1.3016 4.5533993,-1.1034 6.2755729,0.6188 1.722315,1.7223 1.942827,4.3574 0.640815,6.2976 L 4.7378641,1040.73 z"
    +         id="path3654"
    +         style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:url(#linearGradient4193);fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans" />
    +      <path
    +         d="m 7.5,1037.375 c -1.9222418,-6e-4 -3.8524348,0.7274 -5.3125,2.1875 -2.92013057,2.9201 -2.91514915,7.6787 0,10.5937 2.9152066,2.9153 7.7048771,2.9202 10.625,0 2.920123,-2.9201 2.915212,-7.6785 0,-10.5937 -1.45757,-1.4576 -3.3902582,-2.1869 -5.3125,-2.1875 z m 0,1 c 1.6648848,6e-4 3.328535,0.641 4.59375,1.9062 2.530502,2.5305 2.535273,6.6523 0,9.1876 -2.5352721,2.5352 -6.6569944,2.5305 -9.1875,0 -2.53042153,-2.5304 -2.53526535,-6.6523 0,-9.1876 1.2676325,-1.2676 2.9288652,-1.9068 4.59375,-1.9062 z m 0.5,1.0312 c -1.2244702,-0.1129 -2.4651638,0.1911 -3.53125,0.9063 l -0.5,0.3437 0.40625,0.4376 6.9375,6.9062 0.40625,0.4375 0.34375,-0.5 c 1.433292,-2.1358 1.200038,-5.05 -0.6875,-6.9375 -0.943718,-0.9437 -2.1505298,-1.4808 -3.375,-1.5938 z m -0.09375,1 c 0.9977281,0.091 1.9715445,0.5028 2.75,1.2813 1.394159,1.3941 1.636467,3.4297 0.84375,5.0937 l -5.875,-5.875 c 0.7311158,-0.3483 1.4962225,-0.5718 2.28125,-0.5 z m -4.59375,0.9063 -0.34375,0.5 c 0.1015666,-0.1439 0.058823,-0.1238 -0.0625,0.062 L 2.8125,1042 l 0,0.094 c -1.2647854,2.1066 -1.0070498,4.8367 0.8125,6.6562 1.8959155,1.896 4.7998974,2.141 6.9375,0.6875 l 0.5,-0.3437 -0.4375,-0.4376 -6.90625,-6.9062 -0.40625,-0.4375 z m 0.1875,1.6563 5.9375,5.9062 c -1.671311,0.8182 -3.7195859,0.5617 -5.125,-0.8438 -1.3953469,-1.3952 -1.6113966,-3.3991 -0.8125,-5.0624 z"
    +         id="path4173"
    +         style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:url(#linearGradient4185);fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans" />
    +    </g>
    +  </g>
    +</svg>
    
  • GPL/Icons/ModifiedNuvola/closedFolderInView.svg+1262 0 added
    @@ -0,0 +1,1262 @@
    +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    +<!-- Created with Inkscape (http://www.inkscape.org/) -->
    +
    +<svg
    +   xmlns:svg="http://www.w3.org/2000/svg"
    +   xmlns="http://www.w3.org/2000/svg"
    +   xmlns:xlink="http://www.w3.org/1999/xlink"
    +   version="1.1"
    +   width="25"
    +   height="17"
    +   id="svg2">
    +  <defs
    +     id="defs4">
    +    <linearGradient
    +       x1="1.3965347"
    +       y1="2.8009901"
    +       x2="7.6133666"
    +       y2="6.9455447"
    +       id="linearGradient4260"
    +       xlink:href="#linearGradient4254"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="2.6579208"
    +       y1="2.260396"
    +       x2="6.6222773"
    +       y2="3.2934308"
    +       id="linearGradient4239"
    +       xlink:href="#linearGradient4233"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="9.6405945"
    +       y1="1.4495049"
    +       x2="5.4509902"
    +       y2="9.19802"
    +       id="linearGradient4228"
    +       xlink:href="#linearGradient4222"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       id="linearGradient4222">
    +      <stop
    +         id="stop4224"
    +         style="stop-color:#a38300;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4226"
    +         style="stop-color:#6c5600;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4233">
    +      <stop
    +         id="stop4235"
    +         style="stop-color:#32ac00;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4237"
    +         style="stop-color:#116200;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4254">
    +      <stop
    +         id="stop4256"
    +         style="stop-color:#166500;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4258"
    +         style="stop-color:#3a3000;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <clipPath
    +       id="clipPath4146">
    +      <rect
    +         width="8"
    +         height="7"
    +         x="-0.0004619"
    +         y="9"
    +         id="rect4148"
    +         style="opacity:0.55979644;fill:#0060c0;fill-opacity:1;stroke:none" />
    +    </clipPath>
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4777"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(0,2)" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4775"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-2,-1)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="12"
    +       y2="10"
    +       id="linearGradient4773"
    +       xlink:href="#linearGradient4310"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="12"
    +       y2="12"
    +       id="linearGradient4771"
    +       xlink:href="#linearGradient4328"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="6"
    +       y1="5"
    +       x2="10"
    +       y2="7"
    +       id="linearGradient4769"
    +       xlink:href="#linearGradient4302"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="6"
    +       x2="10"
    +       y2="9"
    +       id="linearGradient4767"
    +       xlink:href="#linearGradient4320"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="11"
    +       x2="4"
    +       y2="5"
    +       id="linearGradient4765"
    +       xlink:href="#linearGradient4294"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4763"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(4,0)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4761"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="5"
    +       x2="16"
    +       y2="9"
    +       id="linearGradient4759"
    +       xlink:href="#linearGradient4336"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10.0625"
    +       y1="8.03125"
    +       x2="12"
    +       y2="11"
    +       id="linearGradient4757"
    +       xlink:href="#linearGradient4344"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="16"
    +       y2="12"
    +       id="linearGradient4755"
    +       xlink:href="#linearGradient4366"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="16"
    +       y2="14"
    +       id="linearGradient4753"
    +       xlink:href="#linearGradient4382"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="4"
    +       y1="9"
    +       x2="10"
    +       y2="14"
    +       id="linearGradient4751"
    +       xlink:href="#linearGradient4374"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4707"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(0,2)" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4705"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-2,-1)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="12"
    +       y2="10"
    +       id="linearGradient4703"
    +       xlink:href="#linearGradient4310"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="12"
    +       y2="12"
    +       id="linearGradient4701"
    +       xlink:href="#linearGradient4328"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="6"
    +       y1="5"
    +       x2="10"
    +       y2="7"
    +       id="linearGradient4699"
    +       xlink:href="#linearGradient4302"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="6"
    +       x2="10"
    +       y2="9"
    +       id="linearGradient4697"
    +       xlink:href="#linearGradient4320"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="11"
    +       x2="4"
    +       y2="5"
    +       id="linearGradient4695"
    +       xlink:href="#linearGradient4294"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4693"
    +       xlink:href="#linearGradient3781"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(4,0)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4691"
    +       xlink:href="#linearGradient3769"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="5"
    +       x2="16"
    +       y2="9"
    +       id="linearGradient4689"
    +       xlink:href="#linearGradient3763"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10.0625"
    +       y1="8.03125"
    +       x2="12"
    +       y2="11"
    +       id="linearGradient4687"
    +       xlink:href="#linearGradient3775"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="16"
    +       y2="12"
    +       id="linearGradient4685"
    +       xlink:href="#linearGradient4366"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="16"
    +       y2="14"
    +       id="linearGradient4683"
    +       xlink:href="#linearGradient4382"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="4"
    +       y1="9"
    +       x2="10"
    +       y2="14"
    +       id="linearGradient4681"
    +       xlink:href="#linearGradient4374"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="4"
    +       y1="9"
    +       x2="10"
    +       y2="14"
    +       id="linearGradient4656"
    +       xlink:href="#linearGradient4374"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-3,-25)" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="16"
    +       y2="14"
    +       id="linearGradient4653"
    +       xlink:href="#linearGradient4382"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-3,-27)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="16"
    +       y2="12"
    +       id="linearGradient4650"
    +       xlink:href="#linearGradient4366"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-3,-27)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="16"
    +       y2="12"
    +       id="linearGradient4647"
    +       xlink:href="#linearGradient4366"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="16"
    +       y2="14"
    +       id="linearGradient4645"
    +       xlink:href="#linearGradient4382"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="4"
    +       y1="9"
    +       x2="10"
    +       y2="14"
    +       id="linearGradient4643"
    +       xlink:href="#linearGradient4374"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10.0625"
    +       y1="8.03125"
    +       x2="12"
    +       y2="11"
    +       id="linearGradient4641"
    +       xlink:href="#linearGradient4344"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-1,-28)" />
    +    <linearGradient
    +       x1="8"
    +       y1="5"
    +       x2="16"
    +       y2="9"
    +       id="linearGradient4638"
    +       xlink:href="#linearGradient4336"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-3,-27)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4634"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-1,-28)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4631"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(3,-28)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4628"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(4,0)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4626"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="5"
    +       x2="16"
    +       y2="9"
    +       id="linearGradient4624"
    +       xlink:href="#linearGradient4336"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10.0625"
    +       y1="8.03125"
    +       x2="12"
    +       y2="11"
    +       id="linearGradient4622"
    +       xlink:href="#linearGradient4344"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="11"
    +       x2="4"
    +       y2="5"
    +       id="linearGradient4620"
    +       xlink:href="#linearGradient4294"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-3,-27)" />
    +    <linearGradient
    +       x1="8"
    +       y1="6"
    +       x2="10"
    +       y2="9"
    +       id="linearGradient4617"
    +       xlink:href="#linearGradient4320"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-5,-28)" />
    +    <linearGradient
    +       x1="6"
    +       y1="5"
    +       x2="10"
    +       y2="7"
    +       id="linearGradient4614"
    +       xlink:href="#linearGradient4302"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-5,-28)" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="12"
    +       y2="12"
    +       id="linearGradient4611"
    +       xlink:href="#linearGradient4328"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-5,-28)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="12"
    +       y2="10"
    +       id="linearGradient4608"
    +       xlink:href="#linearGradient4310"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-5,-28)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="12"
    +       y2="10"
    +       id="linearGradient4605"
    +       xlink:href="#linearGradient4310"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="12"
    +       y2="12"
    +       id="linearGradient4603"
    +       xlink:href="#linearGradient4328"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="6"
    +       y1="5"
    +       x2="10"
    +       y2="7"
    +       id="linearGradient4601"
    +       xlink:href="#linearGradient4302"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="6"
    +       x2="10"
    +       y2="9"
    +       id="linearGradient4599"
    +       xlink:href="#linearGradient4320"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="11"
    +       x2="4"
    +       y2="5"
    +       id="linearGradient4597"
    +       xlink:href="#linearGradient4294"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4579"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-5,-28)" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4576"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-3,-25)" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4573"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(0,2)" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4571"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-2,-1)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="12"
    +       y2="10"
    +       id="linearGradient4569"
    +       xlink:href="#linearGradient4310"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="12"
    +       y2="12"
    +       id="linearGradient4567"
    +       xlink:href="#linearGradient4328"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="6"
    +       y1="5"
    +       x2="10"
    +       y2="7"
    +       id="linearGradient4565"
    +       xlink:href="#linearGradient4302"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="6"
    +       x2="10"
    +       y2="9"
    +       id="linearGradient4563"
    +       xlink:href="#linearGradient4320"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="11"
    +       x2="4"
    +       y2="5"
    +       id="linearGradient4561"
    +       xlink:href="#linearGradient4294"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4559"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(4,0)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4557"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="5"
    +       x2="16"
    +       y2="9"
    +       id="linearGradient4555"
    +       xlink:href="#linearGradient4336"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10.0625"
    +       y1="8.03125"
    +       x2="12"
    +       y2="11"
    +       id="linearGradient4553"
    +       xlink:href="#linearGradient4344"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="16"
    +       y2="12"
    +       id="linearGradient4551"
    +       xlink:href="#linearGradient4366"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="16"
    +       y2="14"
    +       id="linearGradient4549"
    +       xlink:href="#linearGradient4382"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="4"
    +       y1="9"
    +       x2="10"
    +       y2="14"
    +       id="linearGradient4547"
    +       xlink:href="#linearGradient4374"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4507"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(0,2)" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4505"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-2,-1)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="12"
    +       y2="10"
    +       id="linearGradient4503"
    +       xlink:href="#linearGradient4310"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="12"
    +       y2="12"
    +       id="linearGradient4501"
    +       xlink:href="#linearGradient4328"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="6"
    +       y1="5"
    +       x2="10"
    +       y2="7"
    +       id="linearGradient4499"
    +       xlink:href="#linearGradient4302"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="6"
    +       x2="10"
    +       y2="9"
    +       id="linearGradient4497"
    +       xlink:href="#linearGradient4320"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="11"
    +       x2="4"
    +       y2="5"
    +       id="linearGradient4495"
    +       xlink:href="#linearGradient4294"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4493"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(4,0)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4491"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="5"
    +       x2="16"
    +       y2="9"
    +       id="linearGradient4489"
    +       xlink:href="#linearGradient4336"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10.0625"
    +       y1="8.03125"
    +       x2="12"
    +       y2="11"
    +       id="linearGradient4487"
    +       xlink:href="#linearGradient4344"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="16"
    +       y2="12"
    +       id="linearGradient4485"
    +       xlink:href="#linearGradient4366"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="16"
    +       y2="14"
    +       id="linearGradient4483"
    +       xlink:href="#linearGradient4382"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="4"
    +       y1="9"
    +       x2="10"
    +       y2="14"
    +       id="linearGradient4481"
    +       xlink:href="#linearGradient4374"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4438"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(0,2)" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4415"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-2,-1)" />
    +    <linearGradient
    +       id="linearGradient4392-6">
    +      <stop
    +         id="stop4394-2"
    +         style="stop-color:#000000;stop-opacity:0.17195767"
    +         offset="0" />
    +      <stop
    +         id="stop4396-8"
    +         style="stop-color:#000000;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4390-0"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="16"
    +       y2="14"
    +       id="linearGradient4380"
    +       xlink:href="#linearGradient4382"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="4"
    +       y1="9"
    +       x2="10"
    +       y2="14"
    +       id="linearGradient4372"
    +       xlink:href="#linearGradient4374"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="16"
    +       y2="12"
    +       id="linearGradient4364"
    +       xlink:href="#linearGradient4366"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4362"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(4,0)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4352"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10.0625"
    +       y1="8.03125"
    +       x2="12"
    +       y2="11"
    +       id="linearGradient4350"
    +       xlink:href="#linearGradient4344"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="5"
    +       x2="16"
    +       y2="9"
    +       id="linearGradient4342"
    +       xlink:href="#linearGradient4336"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="12"
    +       y2="12"
    +       id="linearGradient4326"
    +       xlink:href="#linearGradient4328"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="6"
    +       x2="10"
    +       y2="9"
    +       id="linearGradient4318"
    +       xlink:href="#linearGradient4320"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="12"
    +       y2="10"
    +       id="linearGradient4316"
    +       xlink:href="#linearGradient4310"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="6"
    +       y1="5"
    +       x2="10"
    +       y2="7"
    +       id="linearGradient4308"
    +       xlink:href="#linearGradient4302"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="11"
    +       x2="4"
    +       y2="5"
    +       id="linearGradient4300"
    +       xlink:href="#linearGradient4294"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       id="linearGradient4294">
    +      <stop
    +         id="stop4296"
    +         style="stop-color:#008e00;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4298"
    +         style="stop-color:#00d300;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4302">
    +      <stop
    +         id="stop4304"
    +         style="stop-color:#0fff00;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4306"
    +         style="stop-color:#0fba00;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4310">
    +      <stop
    +         id="stop4312"
    +         style="stop-color:#19ff00;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4314"
    +         style="stop-color:#19a800;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4320">
    +      <stop
    +         id="stop4322"
    +         style="stop-color:#0f8400;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4324"
    +         style="stop-color:#0fba00;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4328">
    +      <stop
    +         id="stop4330"
    +         style="stop-color:#197600;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4332"
    +         style="stop-color:#19a800;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4336">
    +      <stop
    +         id="stop4338"
    +         style="stop-color:#ffff00;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4340"
    +         style="stop-color:#b7b400;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4344">
    +      <stop
    +         id="stop4346"
    +         style="stop-color:#929100;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4348"
    +         style="stop-color:#c4c400;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4354">
    +      <stop
    +         id="stop4356"
    +         style="stop-color:#616000;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4358"
    +         style="stop-color:#bfbf00;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4366">
    +      <stop
    +         id="stop4368"
    +         style="stop-color:#ff0000;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4370"
    +         style="stop-color:#630000;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4374">
    +      <stop
    +         id="stop4376"
    +         style="stop-color:#dc0000;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4378"
    +         style="stop-color:#9a0000;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4382">
    +      <stop
    +         id="stop4384"
    +         style="stop-color:#370000;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4386"
    +         style="stop-color:#ff0000;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient3763">
    +      <stop
    +         id="stop3765"
    +         style="stop-color:#0080ff;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop3767"
    +         style="stop-color:#005bb6;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient3769">
    +      <stop
    +         id="stop3771"
    +         style="stop-color:#003060;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop3773"
    +         style="stop-color:#0060c0;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient3775">
    +      <stop
    +         id="stop3777"
    +         style="stop-color:#004992;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop3779"
    +         style="stop-color:#0062c4;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient3781">
    +      <stop
    +         id="stop3783"
    +         style="stop-color:#003060;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop3785"
    +         style="stop-color:#0060c0;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4254-4">
    +      <stop
    +         id="stop4256-3"
    +         style="stop-color:#166500;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4258-3"
    +         style="stop-color:#3a3000;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4233-2">
    +      <stop
    +         id="stop4235-0"
    +         style="stop-color:#32ac00;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4237-8"
    +         style="stop-color:#116200;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4222-3">
    +      <stop
    +         id="stop4224-8"
    +         style="stop-color:#a38300;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4226-2"
    +         style="stop-color:#6c5600;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       x1="9.6405945"
    +       y1="1.4495049"
    +       x2="5.4509902"
    +       y2="9.19802"
    +       id="linearGradient4228-8"
    +       xlink:href="#linearGradient4222-3"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="2.6579208"
    +       y1="2.260396"
    +       x2="6.6222773"
    +       y2="3.2934308"
    +       id="linearGradient4239-8"
    +       xlink:href="#linearGradient4233-2"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="1.3965347"
    +       y1="2.8009901"
    +       x2="7.6133666"
    +       y2="6.9455447"
    +       id="linearGradient4260-7"
    +       xlink:href="#linearGradient4254-4"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="1.3965347"
    +       y1="2.8009901"
    +       x2="7.6133666"
    +       y2="6.9455447"
    +       id="linearGradient4260-9"
    +       xlink:href="#linearGradient4254-7"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="2.6579208"
    +       y1="2.260396"
    +       x2="6.6222773"
    +       y2="3.2934308"
    +       id="linearGradient4239-0"
    +       xlink:href="#linearGradient4233-1"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="9.6405945"
    +       y1="1.4495049"
    +       x2="5.4509902"
    +       y2="9.19802"
    +       id="linearGradient4228-9"
    +       xlink:href="#linearGradient4222-4"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       id="linearGradient4222-4">
    +      <stop
    +         id="stop4224-1"
    +         style="stop-color:#a38300;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4226-8"
    +         style="stop-color:#6c5600;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4233-1">
    +      <stop
    +         id="stop4235-8"
    +         style="stop-color:#32ac00;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4237-5"
    +         style="stop-color:#116200;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4254-7">
    +      <stop
    +         id="stop4256-33"
    +         style="stop-color:#166500;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4258-8"
    +         style="stop-color:#3a3000;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       x1="1.3965347"
    +       y1="2.8009901"
    +       x2="7.6133666"
    +       y2="6.9455447"
    +       id="linearGradient4260-4"
    +       xlink:href="#linearGradient4254-9"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="2.6579208"
    +       y1="2.260396"
    +       x2="6.6222773"
    +       y2="3.2934308"
    +       id="linearGradient4239-3"
    +       xlink:href="#linearGradient4233-4"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="9.6405945"
    +       y1="1.4495049"
    +       x2="5.4509902"
    +       y2="9.19802"
    +       id="linearGradient4228-91"
    +       xlink:href="#linearGradient4222-9"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       id="linearGradient4222-9">
    +      <stop
    +         id="stop4224-87"
    +         style="stop-color:#a38300;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4226-6"
    +         style="stop-color:#6c5600;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4233-4">
    +      <stop
    +         id="stop4235-81"
    +         style="stop-color:#eb0000;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4237-7"
    +         style="stop-color:#900000;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4254-9">
    +      <stop
    +         id="stop4256-4"
    +         style="stop-color:#7e0000;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4258-0"
    +         style="stop-color:#3a3000;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +  </defs>
    +  <g
    +     transform="translate(0,-1035.3622)"
    +     id="layer1">
    +    <image
    +       xlink:href="../nuvola/16x16/folder_yellow.png"
    +       x="1"
    +       y="1036.3622"
    +       width="16"
    +       height="16"
    +       id="image2998" />
    +    <g
    +       transform="translate(14.000269,1038.3624)"
    +       id="layer2-4">
    +      <path
    +         d="M 9.34375,0 C 9.331893,0.02007096 9.321443,0.04097223 9.3125,0.0625 9.291694,0.0611972 9.270806,0.0611972 9.25,0.0625 9.239262,0.0619942 9.229468,0.06294871 9.21875,0.0625 7.428818,-0.01243524 5.9102713,0.70487297 4.4375,1.40625 2.9559097,2.1118269 1.9397871,2.7910082 0.35734465,2.84375 -0.05907529,2.8522791 -0.26232937,3.5072089 0.07609465,3.75 2.0160738,5.1266314 3.5432986,6.2464747 5.59375,6.5 L 4.0625,9.25 C 3.9616756,9.4398454 4.0018376,9.6942052 4.15625,9.84375 l 1,1 C 5.3695576,11.057374 5.7807905,11.008026 5.9375,10.75 l 5,-9 C 11.038324,1.5601546 10.99816,1.3057948 10.84375,1.15625 l -1,-1 C 9.7346028,0.03783212 9.5657191,-0.02248351 9.40625,0 9.3854438,-0.0013028 9.3645562,-0.0013028 9.34375,0 z m -1.0625,1.1875 -2.5,4.25 C 4.3246653,5.2701854 2.8452361,4.5502621 1.3125,3.5625 2.5816669,3.2796931 3.7528393,2.8007738 4.84375,2.28125 6.0013234,1.7299795 7.1322792,1.3413489 8.28125,1.1875 z m 1.34375,0.125 0.25,0.25 -4.5,8.125 -0.25,-0.25 4.5,-8.125 z"
    +         id="path4241-7"
    +         style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:url(#linearGradient4260-4);fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans" />
    +      <path
    +         d="m 9.5,0.5 1,1 -5,9 -1,-1 5,-9 z"
    +         id="rect3709-2"
    +         style="fill:url(#linearGradient4228-91);fill-opacity:1;stroke:none" />
    +      <path
    +         d="M 0.50737752,3.3857784 C 3.9389568,3.2714061 5.9236512,0.39252559 9.2351487,0.54851491 L 6.0366336,6.0445543 C 3.9943893,5.9091062 2.5496218,4.8349783 0.50737752,3.3857784 z"
    +         id="rect4230-8"
    +         style="fill:url(#linearGradient4239-3);fill-opacity:1;stroke:none" />
    +    </g>
    +  </g>
    +</svg>
    
  • GPL/Icons/ModifiedNuvola/closedFolderLabels.svg+1274 0 added
    @@ -0,0 +1,1274 @@
    +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    +<!-- Created with Inkscape (http://www.inkscape.org/) -->
    +
    +<svg
    +   xmlns:svg="http://www.w3.org/2000/svg"
    +   xmlns="http://www.w3.org/2000/svg"
    +   xmlns:xlink="http://www.w3.org/1999/xlink"
    +   version="1.1"
    +   width="25"
    +   height="17"
    +   id="svg2">
    +  <defs
    +     id="defs4">
    +    <linearGradient
    +       x1="1.3965347"
    +       y1="2.8009901"
    +       x2="7.6133666"
    +       y2="6.9455447"
    +       id="linearGradient4260"
    +       xlink:href="#linearGradient4254"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="2.6579208"
    +       y1="2.260396"
    +       x2="6.6222773"
    +       y2="3.2934308"
    +       id="linearGradient4239"
    +       xlink:href="#linearGradient4233"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="9.6405945"
    +       y1="1.4495049"
    +       x2="5.4509902"
    +       y2="9.19802"
    +       id="linearGradient4228"
    +       xlink:href="#linearGradient4222"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       id="linearGradient4222">
    +      <stop
    +         id="stop4224"
    +         style="stop-color:#a38300;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4226"
    +         style="stop-color:#6c5600;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4233">
    +      <stop
    +         id="stop4235"
    +         style="stop-color:#32ac00;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4237"
    +         style="stop-color:#116200;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4254">
    +      <stop
    +         id="stop4256"
    +         style="stop-color:#166500;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4258"
    +         style="stop-color:#3a3000;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <clipPath
    +       id="clipPath4146">
    +      <rect
    +         width="8"
    +         height="7"
    +         x="-0.0004619"
    +         y="9"
    +         id="rect4148"
    +         style="opacity:0.55979644;fill:#0060c0;fill-opacity:1;stroke:none" />
    +    </clipPath>
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4777"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(0,2)" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4775"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-2,-1)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="12"
    +       y2="10"
    +       id="linearGradient4773"
    +       xlink:href="#linearGradient4310"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="12"
    +       y2="12"
    +       id="linearGradient4771"
    +       xlink:href="#linearGradient4328"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="6"
    +       y1="5"
    +       x2="10"
    +       y2="7"
    +       id="linearGradient4769"
    +       xlink:href="#linearGradient4302"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="6"
    +       x2="10"
    +       y2="9"
    +       id="linearGradient4767"
    +       xlink:href="#linearGradient4320"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="11"
    +       x2="4"
    +       y2="5"
    +       id="linearGradient4765"
    +       xlink:href="#linearGradient4294"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4763"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(4,0)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4761"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="5"
    +       x2="16"
    +       y2="9"
    +       id="linearGradient4759"
    +       xlink:href="#linearGradient4336"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10.0625"
    +       y1="8.03125"
    +       x2="12"
    +       y2="11"
    +       id="linearGradient4757"
    +       xlink:href="#linearGradient4344"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="16"
    +       y2="12"
    +       id="linearGradient4755"
    +       xlink:href="#linearGradient4366"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="16"
    +       y2="14"
    +       id="linearGradient4753"
    +       xlink:href="#linearGradient4382"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="4"
    +       y1="9"
    +       x2="10"
    +       y2="14"
    +       id="linearGradient4751"
    +       xlink:href="#linearGradient4374"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4707"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(0,2)" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4705"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-2,-1)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="12"
    +       y2="10"
    +       id="linearGradient4703"
    +       xlink:href="#linearGradient4310"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="12"
    +       y2="12"
    +       id="linearGradient4701"
    +       xlink:href="#linearGradient4328"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="6"
    +       y1="5"
    +       x2="10"
    +       y2="7"
    +       id="linearGradient4699"
    +       xlink:href="#linearGradient4302"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="6"
    +       x2="10"
    +       y2="9"
    +       id="linearGradient4697"
    +       xlink:href="#linearGradient4320"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="11"
    +       x2="4"
    +       y2="5"
    +       id="linearGradient4695"
    +       xlink:href="#linearGradient4294"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4693"
    +       xlink:href="#linearGradient3781"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(4,0)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4691"
    +       xlink:href="#linearGradient3769"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="5"
    +       x2="16"
    +       y2="9"
    +       id="linearGradient4689"
    +       xlink:href="#linearGradient3763"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10.0625"
    +       y1="8.03125"
    +       x2="12"
    +       y2="11"
    +       id="linearGradient4687"
    +       xlink:href="#linearGradient3775"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="16"
    +       y2="12"
    +       id="linearGradient4685"
    +       xlink:href="#linearGradient4366"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="16"
    +       y2="14"
    +       id="linearGradient4683"
    +       xlink:href="#linearGradient4382"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="4"
    +       y1="9"
    +       x2="10"
    +       y2="14"
    +       id="linearGradient4681"
    +       xlink:href="#linearGradient4374"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="4"
    +       y1="9"
    +       x2="10"
    +       y2="14"
    +       id="linearGradient4656"
    +       xlink:href="#linearGradient4374"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-3,-25)" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="16"
    +       y2="14"
    +       id="linearGradient4653"
    +       xlink:href="#linearGradient4382"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-3,-27)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="16"
    +       y2="12"
    +       id="linearGradient4650"
    +       xlink:href="#linearGradient4366"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-3,-27)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="16"
    +       y2="12"
    +       id="linearGradient4647"
    +       xlink:href="#linearGradient4366"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="16"
    +       y2="14"
    +       id="linearGradient4645"
    +       xlink:href="#linearGradient4382"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="4"
    +       y1="9"
    +       x2="10"
    +       y2="14"
    +       id="linearGradient4643"
    +       xlink:href="#linearGradient4374"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10.0625"
    +       y1="8.03125"
    +       x2="12"
    +       y2="11"
    +       id="linearGradient4641"
    +       xlink:href="#linearGradient4344"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-1,-28)" />
    +    <linearGradient
    +       x1="8"
    +       y1="5"
    +       x2="16"
    +       y2="9"
    +       id="linearGradient4638"
    +       xlink:href="#linearGradient4336"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-3,-27)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4634"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-1,-28)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4631"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(3,-28)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4628"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(4,0)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4626"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="5"
    +       x2="16"
    +       y2="9"
    +       id="linearGradient4624"
    +       xlink:href="#linearGradient4336"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10.0625"
    +       y1="8.03125"
    +       x2="12"
    +       y2="11"
    +       id="linearGradient4622"
    +       xlink:href="#linearGradient4344"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="11"
    +       x2="4"
    +       y2="5"
    +       id="linearGradient4620"
    +       xlink:href="#linearGradient4294"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-3,-27)" />
    +    <linearGradient
    +       x1="8"
    +       y1="6"
    +       x2="10"
    +       y2="9"
    +       id="linearGradient4617"
    +       xlink:href="#linearGradient4320"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-5,-28)" />
    +    <linearGradient
    +       x1="6"
    +       y1="5"
    +       x2="10"
    +       y2="7"
    +       id="linearGradient4614"
    +       xlink:href="#linearGradient4302"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-5,-28)" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="12"
    +       y2="12"
    +       id="linearGradient4611"
    +       xlink:href="#linearGradient4328"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-5,-28)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="12"
    +       y2="10"
    +       id="linearGradient4608"
    +       xlink:href="#linearGradient4310"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-5,-28)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="12"
    +       y2="10"
    +       id="linearGradient4605"
    +       xlink:href="#linearGradient4310"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="12"
    +       y2="12"
    +       id="linearGradient4603"
    +       xlink:href="#linearGradient4328"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="6"
    +       y1="5"
    +       x2="10"
    +       y2="7"
    +       id="linearGradient4601"
    +       xlink:href="#linearGradient4302"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="6"
    +       x2="10"
    +       y2="9"
    +       id="linearGradient4599"
    +       xlink:href="#linearGradient4320"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="11"
    +       x2="4"
    +       y2="5"
    +       id="linearGradient4597"
    +       xlink:href="#linearGradient4294"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4579"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-5,-28)" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4576"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-3,-25)" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4573"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(0,2)" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4571"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-2,-1)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="12"
    +       y2="10"
    +       id="linearGradient4569"
    +       xlink:href="#linearGradient4310"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="12"
    +       y2="12"
    +       id="linearGradient4567"
    +       xlink:href="#linearGradient4328"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="6"
    +       y1="5"
    +       x2="10"
    +       y2="7"
    +       id="linearGradient4565"
    +       xlink:href="#linearGradient4302"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="6"
    +       x2="10"
    +       y2="9"
    +       id="linearGradient4563"
    +       xlink:href="#linearGradient4320"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="11"
    +       x2="4"
    +       y2="5"
    +       id="linearGradient4561"
    +       xlink:href="#linearGradient4294"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4559"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(4,0)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4557"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="5"
    +       x2="16"
    +       y2="9"
    +       id="linearGradient4555"
    +       xlink:href="#linearGradient4336"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10.0625"
    +       y1="8.03125"
    +       x2="12"
    +       y2="11"
    +       id="linearGradient4553"
    +       xlink:href="#linearGradient4344"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="16"
    +       y2="12"
    +       id="linearGradient4551"
    +       xlink:href="#linearGradient4366"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="16"
    +       y2="14"
    +       id="linearGradient4549"
    +       xlink:href="#linearGradient4382"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="4"
    +       y1="9"
    +       x2="10"
    +       y2="14"
    +       id="linearGradient4547"
    +       xlink:href="#linearGradient4374"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4507"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(0,2)" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4505"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-2,-1)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="12"
    +       y2="10"
    +       id="linearGradient4503"
    +       xlink:href="#linearGradient4310"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="12"
    +       y2="12"
    +       id="linearGradient4501"
    +       xlink:href="#linearGradient4328"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="6"
    +       y1="5"
    +       x2="10"
    +       y2="7"
    +       id="linearGradient4499"
    +       xlink:href="#linearGradient4302"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="6"
    +       x2="10"
    +       y2="9"
    +       id="linearGradient4497"
    +       xlink:href="#linearGradient4320"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="11"
    +       x2="4"
    +       y2="5"
    +       id="linearGradient4495"
    +       xlink:href="#linearGradient4294"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4493"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(4,0)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4491"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="5"
    +       x2="16"
    +       y2="9"
    +       id="linearGradient4489"
    +       xlink:href="#linearGradient4336"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10.0625"
    +       y1="8.03125"
    +       x2="12"
    +       y2="11"
    +       id="linearGradient4487"
    +       xlink:href="#linearGradient4344"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="16"
    +       y2="12"
    +       id="linearGradient4485"
    +       xlink:href="#linearGradient4366"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="16"
    +       y2="14"
    +       id="linearGradient4483"
    +       xlink:href="#linearGradient4382"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="4"
    +       y1="9"
    +       x2="10"
    +       y2="14"
    +       id="linearGradient4481"
    +       xlink:href="#linearGradient4374"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4438"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(0,2)" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4415"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-2,-1)" />
    +    <linearGradient
    +       id="linearGradient4392-6">
    +      <stop
    +         id="stop4394-2"
    +         style="stop-color:#000000;stop-opacity:0.17195767"
    +         offset="0" />
    +      <stop
    +         id="stop4396-8"
    +         style="stop-color:#000000;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4390-0"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="16"
    +       y2="14"
    +       id="linearGradient4380"
    +       xlink:href="#linearGradient4382"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="4"
    +       y1="9"
    +       x2="10"
    +       y2="14"
    +       id="linearGradient4372"
    +       xlink:href="#linearGradient4374"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="16"
    +       y2="12"
    +       id="linearGradient4364"
    +       xlink:href="#linearGradient4366"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4362"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(4,0)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4352"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10.0625"
    +       y1="8.03125"
    +       x2="12"
    +       y2="11"
    +       id="linearGradient4350"
    +       xlink:href="#linearGradient4344"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="5"
    +       x2="16"
    +       y2="9"
    +       id="linearGradient4342"
    +       xlink:href="#linearGradient4336"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="12"
    +       y2="12"
    +       id="linearGradient4326"
    +       xlink:href="#linearGradient4328"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="6"
    +       x2="10"
    +       y2="9"
    +       id="linearGradient4318"
    +       xlink:href="#linearGradient4320"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="12"
    +       y2="10"
    +       id="linearGradient4316"
    +       xlink:href="#linearGradient4310"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="6"
    +       y1="5"
    +       x2="10"
    +       y2="7"
    +       id="linearGradient4308"
    +       xlink:href="#linearGradient4302"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="11"
    +       x2="4"
    +       y2="5"
    +       id="linearGradient4300"
    +       xlink:href="#linearGradient4294"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       id="linearGradient4294">
    +      <stop
    +         id="stop4296"
    +         style="stop-color:#008e00;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4298"
    +         style="stop-color:#00d300;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4302">
    +      <stop
    +         id="stop4304"
    +         style="stop-color:#0fff00;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4306"
    +         style="stop-color:#0fba00;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4310">
    +      <stop
    +         id="stop4312"
    +         style="stop-color:#19ff00;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4314"
    +         style="stop-color:#19a800;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4320">
    +      <stop
    +         id="stop4322"
    +         style="stop-color:#0f8400;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4324"
    +         style="stop-color:#0fba00;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4328">
    +      <stop
    +         id="stop4330"
    +         style="stop-color:#197600;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4332"
    +         style="stop-color:#19a800;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4336">
    +      <stop
    +         id="stop4338"
    +         style="stop-color:#ffff00;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4340"
    +         style="stop-color:#b7b400;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4344">
    +      <stop
    +         id="stop4346"
    +         style="stop-color:#929100;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4348"
    +         style="stop-color:#c4c400;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4354">
    +      <stop
    +         id="stop4356"
    +         style="stop-color:#616000;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4358"
    +         style="stop-color:#bfbf00;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4366">
    +      <stop
    +         id="stop4368"
    +         style="stop-color:#ff0000;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4370"
    +         style="stop-color:#630000;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4374">
    +      <stop
    +         id="stop4376"
    +         style="stop-color:#dc0000;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4378"
    +         style="stop-color:#9a0000;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4382">
    +      <stop
    +         id="stop4384"
    +         style="stop-color:#370000;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4386"
    +         style="stop-color:#ff0000;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient3763">
    +      <stop
    +         id="stop3765"
    +         style="stop-color:#0080ff;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop3767"
    +         style="stop-color:#005bb6;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient3769">
    +      <stop
    +         id="stop3771"
    +         style="stop-color:#003060;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop3773"
    +         style="stop-color:#0060c0;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient3775">
    +      <stop
    +         id="stop3777"
    +         style="stop-color:#004992;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop3779"
    +         style="stop-color:#0062c4;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient3781">
    +      <stop
    +         id="stop3783"
    +         style="stop-color:#003060;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop3785"
    +         style="stop-color:#0060c0;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4254-4">
    +      <stop
    +         id="stop4256-3"
    +         style="stop-color:#166500;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4258-3"
    +         style="stop-color:#3a3000;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4233-2">
    +      <stop
    +         id="stop4235-0"
    +         style="stop-color:#32ac00;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4237-8"
    +         style="stop-color:#116200;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4222-3">
    +      <stop
    +         id="stop4224-8"
    +         style="stop-color:#a38300;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4226-2"
    +         style="stop-color:#6c5600;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       x1="9.6405945"
    +       y1="1.4495049"
    +       x2="5.4509902"
    +       y2="9.19802"
    +       id="linearGradient4228-8"
    +       xlink:href="#linearGradient4222-3"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="2.6579208"
    +       y1="2.260396"
    +       x2="6.6222773"
    +       y2="3.2934308"
    +       id="linearGradient4239-8"
    +       xlink:href="#linearGradient4233-2"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="1.3965347"
    +       y1="2.8009901"
    +       x2="7.6133666"
    +       y2="6.9455447"
    +       id="linearGradient4260-7"
    +       xlink:href="#linearGradient4254-4"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="1.3965347"
    +       y1="2.8009901"
    +       x2="7.6133666"
    +       y2="6.9455447"
    +       id="linearGradient4260-9"
    +       xlink:href="#linearGradient4254-7"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="2.6579208"
    +       y1="2.260396"
    +       x2="6.6222773"
    +       y2="3.2934308"
    +       id="linearGradient4239-0"
    +       xlink:href="#linearGradient4233-1"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="9.6405945"
    +       y1="1.4495049"
    +       x2="5.4509902"
    +       y2="9.19802"
    +       id="linearGradient4228-9"
    +       xlink:href="#linearGradient4222-4"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       id="linearGradient4222-4">
    +      <stop
    +         id="stop4224-1"
    +         style="stop-color:#a38300;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4226-8"
    +         style="stop-color:#6c5600;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4233-1">
    +      <stop
    +         id="stop4235-8"
    +         style="stop-color:#32ac00;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4237-5"
    +         style="stop-color:#116200;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4254-7">
    +      <stop
    +         id="stop4256-33"
    +         style="stop-color:#166500;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4258-8"
    +         style="stop-color:#3a3000;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       x1="1.3965347"
    +       y1="2.8009901"
    +       x2="7.6133666"
    +       y2="6.9455447"
    +       id="linearGradient4260-4"
    +       xlink:href="#linearGradient4254-9"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="2.6579208"
    +       y1="2.260396"
    +       x2="6.6222773"
    +       y2="3.2934308"
    +       id="linearGradient4239-3"
    +       xlink:href="#linearGradient4233-4"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="9.6405945"
    +       y1="1.4495049"
    +       x2="5.4509902"
    +       y2="9.19802"
    +       id="linearGradient4228-91"
    +       xlink:href="#linearGradient4222-9"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       id="linearGradient4222-9">
    +      <stop
    +         id="stop4224-87"
    +         style="stop-color:#a38300;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4226-6"
    +         style="stop-color:#6c5600;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4233-4">
    +      <stop
    +         id="stop4235-81"
    +         style="stop-color:#eb0000;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4237-7"
    +         style="stop-color:#900000;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4254-9">
    +      <stop
    +         id="stop4256-4"
    +         style="stop-color:#7e0000;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4258-0"
    +         style="stop-color:#3a3000;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       x1="13"
    +       y1="13"
    +       x2="0"
    +       y2="0"
    +       id="linearGradient3598"
    +       xlink:href="#linearGradient3592"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       id="linearGradient3592">
    +      <stop
    +         id="stop3594"
    +         style="stop-color:#008000;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop3596"
    +         style="stop-color:#ffffff;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +  </defs>
    +  <g
    +     transform="translate(0,-1035.3622)"
    +     id="layer1">
    +    <image
    +       xlink:href="../nuvola/16x16/folder_yellow.png"
    +       x="1"
    +       y="1036.3622"
    +       width="16"
    +       height="16"
    +       id="image2998" />
    +    <g
    +       transform="translate(14.000144,-5.0001885)"
    +       id="layer1-4">
    +      <path
    +         d="m 15,7.5 a 7.5,7.5 0 1 1 -15,0 7.5,7.5 0 1 1 15,0 z"
    +         transform="matrix(0.50001923,0,0,0.50001923,0.24985577,1044.6121)"
    +         id="path2818"
    +         style="fill:url(#linearGradient3598);fill-opacity:1;stroke:#006a00;stroke-width:0.99996156;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
    +    </g>
    +  </g>
    +</svg>
    
  • GPL/Icons/ModifiedNuvola/closedFolderNamespaces.svg+1287 0 added
    @@ -0,0 +1,1287 @@
    +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    +<!-- Created with Inkscape (http://www.inkscape.org/) -->
    +
    +<svg
    +   xmlns:svg="http://www.w3.org/2000/svg"
    +   xmlns="http://www.w3.org/2000/svg"
    +   xmlns:xlink="http://www.w3.org/1999/xlink"
    +   version="1.1"
    +   width="25"
    +   height="17"
    +   id="svg2">
    +  <defs
    +     id="defs4">
    +    <linearGradient
    +       x1="1.3965347"
    +       y1="2.8009901"
    +       x2="7.6133666"
    +       y2="6.9455447"
    +       id="linearGradient4260"
    +       xlink:href="#linearGradient4254"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="2.6579208"
    +       y1="2.260396"
    +       x2="6.6222773"
    +       y2="3.2934308"
    +       id="linearGradient4239"
    +       xlink:href="#linearGradient4233"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="9.6405945"
    +       y1="1.4495049"
    +       x2="5.4509902"
    +       y2="9.19802"
    +       id="linearGradient4228"
    +       xlink:href="#linearGradient4222"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       id="linearGradient4222">
    +      <stop
    +         id="stop4224"
    +         style="stop-color:#a38300;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4226"
    +         style="stop-color:#6c5600;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4233">
    +      <stop
    +         id="stop4235"
    +         style="stop-color:#32ac00;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4237"
    +         style="stop-color:#116200;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4254">
    +      <stop
    +         id="stop4256"
    +         style="stop-color:#166500;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4258"
    +         style="stop-color:#3a3000;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <clipPath
    +       id="clipPath4146">
    +      <rect
    +         width="8"
    +         height="7"
    +         x="-0.0004619"
    +         y="9"
    +         id="rect4148"
    +         style="opacity:0.55979644;fill:#0060c0;fill-opacity:1;stroke:none" />
    +    </clipPath>
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4777"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(0,2)" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4775"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-2,-1)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="12"
    +       y2="10"
    +       id="linearGradient4773"
    +       xlink:href="#linearGradient4310"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="12"
    +       y2="12"
    +       id="linearGradient4771"
    +       xlink:href="#linearGradient4328"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="6"
    +       y1="5"
    +       x2="10"
    +       y2="7"
    +       id="linearGradient4769"
    +       xlink:href="#linearGradient4302"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="6"
    +       x2="10"
    +       y2="9"
    +       id="linearGradient4767"
    +       xlink:href="#linearGradient4320"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="11"
    +       x2="4"
    +       y2="5"
    +       id="linearGradient4765"
    +       xlink:href="#linearGradient4294"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4763"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(4,0)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4761"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="5"
    +       x2="16"
    +       y2="9"
    +       id="linearGradient4759"
    +       xlink:href="#linearGradient4336"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10.0625"
    +       y1="8.03125"
    +       x2="12"
    +       y2="11"
    +       id="linearGradient4757"
    +       xlink:href="#linearGradient4344"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="16"
    +       y2="12"
    +       id="linearGradient4755"
    +       xlink:href="#linearGradient4366"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="16"
    +       y2="14"
    +       id="linearGradient4753"
    +       xlink:href="#linearGradient4382"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="4"
    +       y1="9"
    +       x2="10"
    +       y2="14"
    +       id="linearGradient4751"
    +       xlink:href="#linearGradient4374"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4707"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(0,2)" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4705"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-2,-1)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="12"
    +       y2="10"
    +       id="linearGradient4703"
    +       xlink:href="#linearGradient4310"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="12"
    +       y2="12"
    +       id="linearGradient4701"
    +       xlink:href="#linearGradient4328"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="6"
    +       y1="5"
    +       x2="10"
    +       y2="7"
    +       id="linearGradient4699"
    +       xlink:href="#linearGradient4302"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="6"
    +       x2="10"
    +       y2="9"
    +       id="linearGradient4697"
    +       xlink:href="#linearGradient4320"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="11"
    +       x2="4"
    +       y2="5"
    +       id="linearGradient4695"
    +       xlink:href="#linearGradient4294"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4693"
    +       xlink:href="#linearGradient3781"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(4,0)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4691"
    +       xlink:href="#linearGradient3769"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="5"
    +       x2="16"
    +       y2="9"
    +       id="linearGradient4689"
    +       xlink:href="#linearGradient3763"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10.0625"
    +       y1="8.03125"
    +       x2="12"
    +       y2="11"
    +       id="linearGradient4687"
    +       xlink:href="#linearGradient3775"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="16"
    +       y2="12"
    +       id="linearGradient4685"
    +       xlink:href="#linearGradient4366"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="16"
    +       y2="14"
    +       id="linearGradient4683"
    +       xlink:href="#linearGradient4382"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="4"
    +       y1="9"
    +       x2="10"
    +       y2="14"
    +       id="linearGradient4681"
    +       xlink:href="#linearGradient4374"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="4"
    +       y1="9"
    +       x2="10"
    +       y2="14"
    +       id="linearGradient4656"
    +       xlink:href="#linearGradient4374"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-3,-25)" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="16"
    +       y2="14"
    +       id="linearGradient4653"
    +       xlink:href="#linearGradient4382"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-3,-27)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="16"
    +       y2="12"
    +       id="linearGradient4650"
    +       xlink:href="#linearGradient4366"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-3,-27)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="16"
    +       y2="12"
    +       id="linearGradient4647"
    +       xlink:href="#linearGradient4366"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="16"
    +       y2="14"
    +       id="linearGradient4645"
    +       xlink:href="#linearGradient4382"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="4"
    +       y1="9"
    +       x2="10"
    +       y2="14"
    +       id="linearGradient4643"
    +       xlink:href="#linearGradient4374"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10.0625"
    +       y1="8.03125"
    +       x2="12"
    +       y2="11"
    +       id="linearGradient4641"
    +       xlink:href="#linearGradient4344"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-1,-28)" />
    +    <linearGradient
    +       x1="8"
    +       y1="5"
    +       x2="16"
    +       y2="9"
    +       id="linearGradient4638"
    +       xlink:href="#linearGradient4336"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-3,-27)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4634"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-1,-28)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4631"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(3,-28)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4628"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(4,0)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4626"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="5"
    +       x2="16"
    +       y2="9"
    +       id="linearGradient4624"
    +       xlink:href="#linearGradient4336"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10.0625"
    +       y1="8.03125"
    +       x2="12"
    +       y2="11"
    +       id="linearGradient4622"
    +       xlink:href="#linearGradient4344"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="11"
    +       x2="4"
    +       y2="5"
    +       id="linearGradient4620"
    +       xlink:href="#linearGradient4294"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-3,-27)" />
    +    <linearGradient
    +       x1="8"
    +       y1="6"
    +       x2="10"
    +       y2="9"
    +       id="linearGradient4617"
    +       xlink:href="#linearGradient4320"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-5,-28)" />
    +    <linearGradient
    +       x1="6"
    +       y1="5"
    +       x2="10"
    +       y2="7"
    +       id="linearGradient4614"
    +       xlink:href="#linearGradient4302"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-5,-28)" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="12"
    +       y2="12"
    +       id="linearGradient4611"
    +       xlink:href="#linearGradient4328"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-5,-28)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="12"
    +       y2="10"
    +       id="linearGradient4608"
    +       xlink:href="#linearGradient4310"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-5,-28)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="12"
    +       y2="10"
    +       id="linearGradient4605"
    +       xlink:href="#linearGradient4310"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="12"
    +       y2="12"
    +       id="linearGradient4603"
    +       xlink:href="#linearGradient4328"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="6"
    +       y1="5"
    +       x2="10"
    +       y2="7"
    +       id="linearGradient4601"
    +       xlink:href="#linearGradient4302"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="6"
    +       x2="10"
    +       y2="9"
    +       id="linearGradient4599"
    +       xlink:href="#linearGradient4320"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="11"
    +       x2="4"
    +       y2="5"
    +       id="linearGradient4597"
    +       xlink:href="#linearGradient4294"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4579"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-5,-28)" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4576"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-3,-25)" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4573"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(0,2)" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4571"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-2,-1)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="12"
    +       y2="10"
    +       id="linearGradient4569"
    +       xlink:href="#linearGradient4310"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="12"
    +       y2="12"
    +       id="linearGradient4567"
    +       xlink:href="#linearGradient4328"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="6"
    +       y1="5"
    +       x2="10"
    +       y2="7"
    +       id="linearGradient4565"
    +       xlink:href="#linearGradient4302"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="6"
    +       x2="10"
    +       y2="9"
    +       id="linearGradient4563"
    +       xlink:href="#linearGradient4320"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="11"
    +       x2="4"
    +       y2="5"
    +       id="linearGradient4561"
    +       xlink:href="#linearGradient4294"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4559"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(4,0)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4557"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="5"
    +       x2="16"
    +       y2="9"
    +       id="linearGradient4555"
    +       xlink:href="#linearGradient4336"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10.0625"
    +       y1="8.03125"
    +       x2="12"
    +       y2="11"
    +       id="linearGradient4553"
    +       xlink:href="#linearGradient4344"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="16"
    +       y2="12"
    +       id="linearGradient4551"
    +       xlink:href="#linearGradient4366"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="16"
    +       y2="14"
    +       id="linearGradient4549"
    +       xlink:href="#linearGradient4382"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="4"
    +       y1="9"
    +       x2="10"
    +       y2="14"
    +       id="linearGradient4547"
    +       xlink:href="#linearGradient4374"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4507"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(0,2)" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4505"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-2,-1)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="12"
    +       y2="10"
    +       id="linearGradient4503"
    +       xlink:href="#linearGradient4310"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="12"
    +       y2="12"
    +       id="linearGradient4501"
    +       xlink:href="#linearGradient4328"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="6"
    +       y1="5"
    +       x2="10"
    +       y2="7"
    +       id="linearGradient4499"
    +       xlink:href="#linearGradient4302"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="6"
    +       x2="10"
    +       y2="9"
    +       id="linearGradient4497"
    +       xlink:href="#linearGradient4320"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="11"
    +       x2="4"
    +       y2="5"
    +       id="linearGradient4495"
    +       xlink:href="#linearGradient4294"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4493"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(4,0)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4491"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="5"
    +       x2="16"
    +       y2="9"
    +       id="linearGradient4489"
    +       xlink:href="#linearGradient4336"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10.0625"
    +       y1="8.03125"
    +       x2="12"
    +       y2="11"
    +       id="linearGradient4487"
    +       xlink:href="#linearGradient4344"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="16"
    +       y2="12"
    +       id="linearGradient4485"
    +       xlink:href="#linearGradient4366"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="16"
    +       y2="14"
    +       id="linearGradient4483"
    +       xlink:href="#linearGradient4382"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="4"
    +       y1="9"
    +       x2="10"
    +       y2="14"
    +       id="linearGradient4481"
    +       xlink:href="#linearGradient4374"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4438"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(0,2)" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4415"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-2,-1)" />
    +    <linearGradient
    +       id="linearGradient4392-6">
    +      <stop
    +         id="stop4394-2"
    +         style="stop-color:#000000;stop-opacity:0.17195767"
    +         offset="0" />
    +      <stop
    +         id="stop4396-8"
    +         style="stop-color:#000000;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4390-0"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="16"
    +       y2="14"
    +       id="linearGradient4380"
    +       xlink:href="#linearGradient4382"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="4"
    +       y1="9"
    +       x2="10"
    +       y2="14"
    +       id="linearGradient4372"
    +       xlink:href="#linearGradient4374"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="16"
    +       y2="12"
    +       id="linearGradient4364"
    +       xlink:href="#linearGradient4366"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4362"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(4,0)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4352"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10.0625"
    +       y1="8.03125"
    +       x2="12"
    +       y2="11"
    +       id="linearGradient4350"
    +       xlink:href="#linearGradient4344"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="5"
    +       x2="16"
    +       y2="9"
    +       id="linearGradient4342"
    +       xlink:href="#linearGradient4336"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="12"
    +       y2="12"
    +       id="linearGradient4326"
    +       xlink:href="#linearGradient4328"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="6"
    +       x2="10"
    +       y2="9"
    +       id="linearGradient4318"
    +       xlink:href="#linearGradient4320"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="12"
    +       y2="10"
    +       id="linearGradient4316"
    +       xlink:href="#linearGradient4310"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="6"
    +       y1="5"
    +       x2="10"
    +       y2="7"
    +       id="linearGradient4308"
    +       xlink:href="#linearGradient4302"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="11"
    +       x2="4"
    +       y2="5"
    +       id="linearGradient4300"
    +       xlink:href="#linearGradient4294"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       id="linearGradient4294">
    +      <stop
    +         id="stop4296"
    +         style="stop-color:#008e00;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4298"
    +         style="stop-color:#00d300;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4302">
    +      <stop
    +         id="stop4304"
    +         style="stop-color:#0fff00;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4306"
    +         style="stop-color:#0fba00;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4310">
    +      <stop
    +         id="stop4312"
    +         style="stop-color:#19ff00;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4314"
    +         style="stop-color:#19a800;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4320">
    +      <stop
    +         id="stop4322"
    +         style="stop-color:#0f8400;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4324"
    +         style="stop-color:#0fba00;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4328">
    +      <stop
    +         id="stop4330"
    +         style="stop-color:#197600;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4332"
    +         style="stop-color:#19a800;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4336">
    +      <stop
    +         id="stop4338"
    +         style="stop-color:#ffff00;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4340"
    +         style="stop-color:#b7b400;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4344">
    +      <stop
    +         id="stop4346"
    +         style="stop-color:#929100;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4348"
    +         style="stop-color:#c4c400;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4354">
    +      <stop
    +         id="stop4356"
    +         style="stop-color:#616000;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4358"
    +         style="stop-color:#bfbf00;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4366">
    +      <stop
    +         id="stop4368"
    +         style="stop-color:#ff0000;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4370"
    +         style="stop-color:#630000;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4374">
    +      <stop
    +         id="stop4376"
    +         style="stop-color:#dc0000;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4378"
    +         style="stop-color:#9a0000;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4382">
    +      <stop
    +         id="stop4384"
    +         style="stop-color:#370000;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4386"
    +         style="stop-color:#ff0000;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient3763">
    +      <stop
    +         id="stop3765"
    +         style="stop-color:#0080ff;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop3767"
    +         style="stop-color:#005bb6;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient3769">
    +      <stop
    +         id="stop3771"
    +         style="stop-color:#003060;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop3773"
    +         style="stop-color:#0060c0;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient3775">
    +      <stop
    +         id="stop3777"
    +         style="stop-color:#004992;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop3779"
    +         style="stop-color:#0062c4;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient3781">
    +      <stop
    +         id="stop3783"
    +         style="stop-color:#003060;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop3785"
    +         style="stop-color:#0060c0;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4254-4">
    +      <stop
    +         id="stop4256-3"
    +         style="stop-color:#166500;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4258-3"
    +         style="stop-color:#3a3000;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4233-2">
    +      <stop
    +         id="stop4235-0"
    +         style="stop-color:#32ac00;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4237-8"
    +         style="stop-color:#116200;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4222-3">
    +      <stop
    +         id="stop4224-8"
    +         style="stop-color:#a38300;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4226-2"
    +         style="stop-color:#6c5600;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       x1="9.6405945"
    +       y1="1.4495049"
    +       x2="5.4509902"
    +       y2="9.19802"
    +       id="linearGradient4228-8"
    +       xlink:href="#linearGradient4222-3"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="2.6579208"
    +       y1="2.260396"
    +       x2="6.6222773"
    +       y2="3.2934308"
    +       id="linearGradient4239-8"
    +       xlink:href="#linearGradient4233-2"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="1.3965347"
    +       y1="2.8009901"
    +       x2="7.6133666"
    +       y2="6.9455447"
    +       id="linearGradient4260-7"
    +       xlink:href="#linearGradient4254-4"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="1.3965347"
    +       y1="2.8009901"
    +       x2="7.6133666"
    +       y2="6.9455447"
    +       id="linearGradient4260-9"
    +       xlink:href="#linearGradient4254-7"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="2.6579208"
    +       y1="2.260396"
    +       x2="6.6222773"
    +       y2="3.2934308"
    +       id="linearGradient4239-0"
    +       xlink:href="#linearGradient4233-1"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="9.6405945"
    +       y1="1.4495049"
    +       x2="5.4509902"
    +       y2="9.19802"
    +       id="linearGradient4228-9"
    +       xlink:href="#linearGradient4222-4"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       id="linearGradient4222-4">
    +      <stop
    +         id="stop4224-1"
    +         style="stop-color:#a38300;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4226-8"
    +         style="stop-color:#6c5600;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4233-1">
    +      <stop
    +         id="stop4235-8"
    +         style="stop-color:#32ac00;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4237-5"
    +         style="stop-color:#116200;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4254-7">
    +      <stop
    +         id="stop4256-33"
    +         style="stop-color:#166500;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4258-8"
    +         style="stop-color:#3a3000;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       x1="1.3965347"
    +       y1="2.8009901"
    +       x2="7.6133666"
    +       y2="6.9455447"
    +       id="linearGradient4260-4"
    +       xlink:href="#linearGradient4254-9"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="2.6579208"
    +       y1="2.260396"
    +       x2="6.6222773"
    +       y2="3.2934308"
    +       id="linearGradient4239-3"
    +       xlink:href="#linearGradient4233-4"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="9.6405945"
    +       y1="1.4495049"
    +       x2="5.4509902"
    +       y2="9.19802"
    +       id="linearGradient4228-91"
    +       xlink:href="#linearGradient4222-9"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       id="linearGradient4222-9">
    +      <stop
    +         id="stop4224-87"
    +         style="stop-color:#a38300;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4226-6"
    +         style="stop-color:#6c5600;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4233-4">
    +      <stop
    +         id="stop4235-81"
    +         style="stop-color:#eb0000;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4237-7"
    +         style="stop-color:#900000;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4254-9">
    +      <stop
    +         id="stop4256-4"
    +         style="stop-color:#7e0000;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4258-0"
    +         style="stop-color:#3a3000;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       x1="13"
    +       y1="13"
    +       x2="0"
    +       y2="0"
    +       id="linearGradient3598"
    +       xlink:href="#linearGradient3592"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       id="linearGradient3592">
    +      <stop
    +         id="stop3594"
    +         style="stop-color:#008000;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop3596"
    +         style="stop-color:#ffffff;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +  </defs>
    +  <g
    +     transform="translate(0,-1035.3622)"
    +     id="layer1">
    +    <image
    +       xlink:href="../nuvola/16x16/folder_yellow.png"
    +       x="1"
    +       y="1036.3622"
    +       width="16"
    +       height="16"
    +       id="image2998" />
    +    <g
    +       transform="translate(15,1034.3622)"
    +       id="layer1-8">
    +      <g
    +         transform="scale(0.85235195,1.1732243)"
    +         id="text3638"
    +         style="font-size:10.1596756px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans">
    +        <path
    +           d="m 4.692897,12.78514 0,0.852492 -1.076489,0 C 2.8954372,13.637631 2.3695952,13.492114 2.0388802,13.201084 1.7081586,12.91005 1.5427995,12.445391 1.5428023,11.807105 l 0,-0.95247 C 1.5427995,10.358559 1.4535056,10.014612 1.2749202,9.8227931 1.0963298,9.6276714 0.7722259,9.3769525 0.30260753,9.3769501 L 0,9.3769501 0,8.5237383 l 0.30260753,0 C 0.7722259,8.5237419 1.0963298,8.3279486 1.2749202,8.1361282 1.4535056,7.9443154 1.5427995,7.6003684 1.5428023,7.1042861 l 0,-1.0169597 C 1.5427995,5.449046 1.7081586,4.9860404 2.0388802,4.6983082 2.3695952,4.4072834 2.8954372,4.2617674 3.616408,4.2617597 l 1.076489,0 0,0.8531448 -0.3422937,0 C 3.8842849,5.1149111 3.5800241,5.3094409 3.4378199,5.4549506 3.2989135,5.5971658 3.2294627,6.0443389 3.2294672,6.5139534 l 0,0.8234893 C 3.2294627,7.8566751 3.1550511,8.2336939 3.0062321,8.4685004 2.8574046,8.7033138 2.601098,8.8620586 2.2373114,8.9447352 2.6044052,9.0340321 2.8607118,9.1960841 3.0062321,9.4308915 3.1550511,9.665704 3.2294627,10.041069 3.2294672,10.556988 l 0,0.82349 c -4.5e-6,0.472927 0.069446,0.921754 0.2083527,1.063964 0.1422042,0.145515 0.446465,0.340697 0.9127834,0.340698 l 0.3422937,0"
    +           id="path3663"
    +           style="font-weight:bold" />
    +      </g>
    +      <g
    +         transform="matrix(-0.85235195,0,0,1.1732243,10,-1.2568576e-6)"
    +         id="g3665"
    +         style="font-size:10.1596756px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans">
    +        <path
    +           d="m 4.692897,12.78514 0,0.852492 -1.076489,0 C 2.8954372,13.637631 2.3695952,13.492114 2.0388802,13.201084 1.7081586,12.91005 1.5427995,12.445391 1.5428023,11.807105 l 0,-0.95247 C 1.5427995,10.358559 1.4535056,10.014612 1.2749202,9.8227931 1.0963298,9.6276714 0.7722259,9.3769525 0.30260753,9.3769501 L 0,9.3769501 0,8.5237383 l 0.30260753,0 C 0.7722259,8.5237419 1.0963298,8.3279486 1.2749202,8.1361282 1.4535056,7.9443154 1.5427995,7.6003684 1.5428023,7.1042861 l 0,-1.0169597 C 1.5427995,5.449046 1.7081586,4.9860404 2.0388802,4.6983082 2.3695952,4.4072834 2.8954372,4.2617674 3.616408,4.2617597 l 1.076489,0 0,0.8531448 -0.3422937,0 C 3.8842849,5.1149111 3.5800241,5.3094409 3.4378199,5.4549506 3.2989135,5.5971658 3.2294627,6.0443389 3.2294672,6.5139534 l 0,0.8234893 C 3.2294627,7.8566751 3.1550511,8.2336939 3.0062321,8.4685004 2.8574046,8.7033138 2.601098,8.8620586 2.2373114,8.9447352 2.6044052,9.0340321 2.8607118,9.1960841 3.0062321,9.4308915 3.1550511,9.665704 3.2294627,10.041069 3.2294672,10.556988 l 0,0.82349 c -4.5e-6,0.472927 0.069446,0.921754 0.2083527,1.063964 0.1422042,0.145515 0.446465,0.340697 0.9127834,0.340698 l 0.3422937,0"
    +           id="path3667"
    +           style="font-weight:bold" />
    +      </g>
    +    </g>
    +  </g>
    +</svg>
    
  • GPL/Icons/ModifiedNuvola/closedFolder.svg+150 0 added
    @@ -0,0 +1,150 @@
    +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    +<!-- Created with Inkscape (http://www.inkscape.org/) -->
    +
    +<svg
    +   xmlns:svg="http://www.w3.org/2000/svg"
    +   xmlns="http://www.w3.org/2000/svg"
    +   xmlns:xlink="http://www.w3.org/1999/xlink"
    +   version="1.1"
    +   width="25"
    +   height="17"
    +   id="svg2">
    +  <defs
    +     id="defs4">
    +    <linearGradient
    +       x1="1.3965347"
    +       y1="2.8009901"
    +       x2="7.6133666"
    +       y2="6.9455447"
    +       id="linearGradient4260"
    +       xlink:href="#linearGradient4254"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="2.6579208"
    +       y1="2.260396"
    +       x2="6.6222773"
    +       y2="3.2934308"
    +       id="linearGradient4239"
    +       xlink:href="#linearGradient4233"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="9.6405945"
    +       y1="1.4495049"
    +       x2="5.4509902"
    +       y2="9.19802"
    +       id="linearGradient4228"
    +       xlink:href="#linearGradient4222"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       id="linearGradient4222">
    +      <stop
    +         id="stop4224"
    +         style="stop-color:#a38300;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4226"
    +         style="stop-color:#6c5600;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4233">
    +      <stop
    +         id="stop4235"
    +         style="stop-color:#32ac00;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4237"
    +         style="stop-color:#116200;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4254">
    +      <stop
    +         id="stop4256"
    +         style="stop-color:#166500;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4258"
    +         style="stop-color:#3a3000;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <clipPath
    +       id="clipPath4146">
    +      <rect
    +         width="8"
    +         height="7"
    +         x="-0.0004619"
    +         y="9"
    +         id="rect4148"
    +         style="opacity:0.55979644;fill:#0060c0;fill-opacity:1;stroke:none" />
    +    </clipPath>
    +    <linearGradient
    +       x1="4"
    +       y1="1045.5497"
    +       x2="-6.0625"
    +       y2="1026.2684"
    +       id="linearGradient3693"
    +       xlink:href="#linearGradient3613"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(2,2)" />
    +    <linearGradient
    +       x1="-5.095274"
    +       y1="1033.3518"
    +       x2="13.163674"
    +       y2="1058.4865"
    +       id="linearGradient3647"
    +       xlink:href="#linearGradient3639"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(1.96875,2)" />
    +    <linearGradient
    +       x1="-5.095274"
    +       y1="1033.3518"
    +       x2="13.163674"
    +       y2="1058.4865"
    +       id="linearGradient3633"
    +       xlink:href="#linearGradient3639"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-0.03124999,0)" />
    +    <linearGradient
    +       x1="4"
    +       y1="1045.5497"
    +       x2="-6.0625"
    +       y2="1026.2684"
    +       id="linearGradient3619"
    +       xlink:href="#linearGradient3613"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       id="linearGradient3613">
    +      <stop
    +         id="stop3615"
    +         style="stop-color:#ffffff;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop3617"
    +         style="stop-color:#000000;stop-opacity:0.72944295"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient3639">
    +      <stop
    +         id="stop3641"
    +         style="stop-color:#000000;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop3643"
    +         style="stop-color:#ffffff;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +  </defs>
    +  <g
    +     transform="translate(0,-1035.3622)"
    +     id="layer1">
    +    <image
    +       xlink:href="../nuvola/16x16/folder_yellow.png"
    +       x="1"
    +       y="1036.3622"
    +       width="16"
    +       height="16"
    +       id="image2998" />
    +  </g>
    +</svg>
    
  • GPL/Icons/ModifiedNuvola/closedProject.svg+1371 0 added
    @@ -0,0 +1,1371 @@
    +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    +<!-- Created with Inkscape (http://www.inkscape.org/) -->
    +
    +<svg
    +   xmlns:svg="http://www.w3.org/2000/svg"
    +   xmlns="http://www.w3.org/2000/svg"
    +   xmlns:xlink="http://www.w3.org/1999/xlink"
    +   version="1.1"
    +   width="16"
    +   height="16"
    +   id="svg2">
    +  <defs
    +     id="defs4">
    +    <linearGradient
    +       x1="1.3965347"
    +       y1="2.8009901"
    +       x2="7.6133666"
    +       y2="6.9455447"
    +       id="linearGradient4260"
    +       xlink:href="#linearGradient4254"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="2.6579208"
    +       y1="2.260396"
    +       x2="6.6222773"
    +       y2="3.2934308"
    +       id="linearGradient4239"
    +       xlink:href="#linearGradient4233"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="9.6405945"
    +       y1="1.4495049"
    +       x2="5.4509902"
    +       y2="9.19802"
    +       id="linearGradient4228"
    +       xlink:href="#linearGradient4222"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       id="linearGradient4222">
    +      <stop
    +         id="stop4224"
    +         style="stop-color:#a38300;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4226"
    +         style="stop-color:#6c5600;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4233">
    +      <stop
    +         id="stop4235"
    +         style="stop-color:#32ac00;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4237"
    +         style="stop-color:#116200;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4254">
    +      <stop
    +         id="stop4256"
    +         style="stop-color:#166500;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4258"
    +         style="stop-color:#3a3000;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <clipPath
    +       id="clipPath4146">
    +      <rect
    +         width="8"
    +         height="7"
    +         x="-0.0004619"
    +         y="9"
    +         id="rect4148"
    +         style="opacity:0.55979644;fill:#0060c0;fill-opacity:1;stroke:none" />
    +    </clipPath>
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4777"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(0,2)" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4775"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-2,-1)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="12"
    +       y2="10"
    +       id="linearGradient4773"
    +       xlink:href="#linearGradient4310"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="12"
    +       y2="12"
    +       id="linearGradient4771"
    +       xlink:href="#linearGradient4328"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="6"
    +       y1="5"
    +       x2="10"
    +       y2="7"
    +       id="linearGradient4769"
    +       xlink:href="#linearGradient4302"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="6"
    +       x2="10"
    +       y2="9"
    +       id="linearGradient4767"
    +       xlink:href="#linearGradient4320"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="11"
    +       x2="4"
    +       y2="5"
    +       id="linearGradient4765"
    +       xlink:href="#linearGradient4294"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4763"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(4,0)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4761"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="5"
    +       x2="16"
    +       y2="9"
    +       id="linearGradient4759"
    +       xlink:href="#linearGradient4336"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10.0625"
    +       y1="8.03125"
    +       x2="12"
    +       y2="11"
    +       id="linearGradient4757"
    +       xlink:href="#linearGradient4344"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="16"
    +       y2="12"
    +       id="linearGradient4755"
    +       xlink:href="#linearGradient4366"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="16"
    +       y2="14"
    +       id="linearGradient4753"
    +       xlink:href="#linearGradient4382"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="4"
    +       y1="9"
    +       x2="10"
    +       y2="14"
    +       id="linearGradient4751"
    +       xlink:href="#linearGradient4374"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4707"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(0,2)" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4705"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-2,-1)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="12"
    +       y2="10"
    +       id="linearGradient4703"
    +       xlink:href="#linearGradient4310"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="12"
    +       y2="12"
    +       id="linearGradient4701"
    +       xlink:href="#linearGradient4328"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="6"
    +       y1="5"
    +       x2="10"
    +       y2="7"
    +       id="linearGradient4699"
    +       xlink:href="#linearGradient4302"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="6"
    +       x2="10"
    +       y2="9"
    +       id="linearGradient4697"
    +       xlink:href="#linearGradient4320"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="11"
    +       x2="4"
    +       y2="5"
    +       id="linearGradient4695"
    +       xlink:href="#linearGradient4294"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4693"
    +       xlink:href="#linearGradient3781"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(4,0)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4691"
    +       xlink:href="#linearGradient3769"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="5"
    +       x2="16"
    +       y2="9"
    +       id="linearGradient4689"
    +       xlink:href="#linearGradient3763"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10.0625"
    +       y1="8.03125"
    +       x2="12"
    +       y2="11"
    +       id="linearGradient4687"
    +       xlink:href="#linearGradient3775"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="16"
    +       y2="12"
    +       id="linearGradient4685"
    +       xlink:href="#linearGradient4366"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="16"
    +       y2="14"
    +       id="linearGradient4683"
    +       xlink:href="#linearGradient4382"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="4"
    +       y1="9"
    +       x2="10"
    +       y2="14"
    +       id="linearGradient4681"
    +       xlink:href="#linearGradient4374"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="4"
    +       y1="9"
    +       x2="10"
    +       y2="14"
    +       id="linearGradient4656"
    +       xlink:href="#linearGradient4374"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-3,-25)" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="16"
    +       y2="14"
    +       id="linearGradient4653"
    +       xlink:href="#linearGradient4382"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-3,-27)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="16"
    +       y2="12"
    +       id="linearGradient4650"
    +       xlink:href="#linearGradient4366"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-3,-27)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="16"
    +       y2="12"
    +       id="linearGradient4647"
    +       xlink:href="#linearGradient4366"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="16"
    +       y2="14"
    +       id="linearGradient4645"
    +       xlink:href="#linearGradient4382"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="4"
    +       y1="9"
    +       x2="10"
    +       y2="14"
    +       id="linearGradient4643"
    +       xlink:href="#linearGradient4374"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10.0625"
    +       y1="8.03125"
    +       x2="12"
    +       y2="11"
    +       id="linearGradient4641"
    +       xlink:href="#linearGradient4344"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-1,-28)" />
    +    <linearGradient
    +       x1="8"
    +       y1="5"
    +       x2="16"
    +       y2="9"
    +       id="linearGradient4638"
    +       xlink:href="#linearGradient4336"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-3,-27)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4634"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-1,-28)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4631"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(3,-28)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4628"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(4,0)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4626"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="5"
    +       x2="16"
    +       y2="9"
    +       id="linearGradient4624"
    +       xlink:href="#linearGradient4336"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10.0625"
    +       y1="8.03125"
    +       x2="12"
    +       y2="11"
    +       id="linearGradient4622"
    +       xlink:href="#linearGradient4344"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="11"
    +       x2="4"
    +       y2="5"
    +       id="linearGradient4620"
    +       xlink:href="#linearGradient4294"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-3,-27)" />
    +    <linearGradient
    +       x1="8"
    +       y1="6"
    +       x2="10"
    +       y2="9"
    +       id="linearGradient4617"
    +       xlink:href="#linearGradient4320"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-5,-28)" />
    +    <linearGradient
    +       x1="6"
    +       y1="5"
    +       x2="10"
    +       y2="7"
    +       id="linearGradient4614"
    +       xlink:href="#linearGradient4302"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-5,-28)" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="12"
    +       y2="12"
    +       id="linearGradient4611"
    +       xlink:href="#linearGradient4328"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-5,-28)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="12"
    +       y2="10"
    +       id="linearGradient4608"
    +       xlink:href="#linearGradient4310"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-5,-28)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="12"
    +       y2="10"
    +       id="linearGradient4605"
    +       xlink:href="#linearGradient4310"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="12"
    +       y2="12"
    +       id="linearGradient4603"
    +       xlink:href="#linearGradient4328"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="6"
    +       y1="5"
    +       x2="10"
    +       y2="7"
    +       id="linearGradient4601"
    +       xlink:href="#linearGradient4302"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="6"
    +       x2="10"
    +       y2="9"
    +       id="linearGradient4599"
    +       xlink:href="#linearGradient4320"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="11"
    +       x2="4"
    +       y2="5"
    +       id="linearGradient4597"
    +       xlink:href="#linearGradient4294"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4579"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-5,-28)" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4576"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-3,-25)" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4573"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(0,2)" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4571"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-2,-1)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="12"
    +       y2="10"
    +       id="linearGradient4569"
    +       xlink:href="#linearGradient4310"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="12"
    +       y2="12"
    +       id="linearGradient4567"
    +       xlink:href="#linearGradient4328"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="6"
    +       y1="5"
    +       x2="10"
    +       y2="7"
    +       id="linearGradient4565"
    +       xlink:href="#linearGradient4302"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="6"
    +       x2="10"
    +       y2="9"
    +       id="linearGradient4563"
    +       xlink:href="#linearGradient4320"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="11"
    +       x2="4"
    +       y2="5"
    +       id="linearGradient4561"
    +       xlink:href="#linearGradient4294"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4559"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(4,0)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4557"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="5"
    +       x2="16"
    +       y2="9"
    +       id="linearGradient4555"
    +       xlink:href="#linearGradient4336"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10.0625"
    +       y1="8.03125"
    +       x2="12"
    +       y2="11"
    +       id="linearGradient4553"
    +       xlink:href="#linearGradient4344"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="16"
    +       y2="12"
    +       id="linearGradient4551"
    +       xlink:href="#linearGradient4366"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="16"
    +       y2="14"
    +       id="linearGradient4549"
    +       xlink:href="#linearGradient4382"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="4"
    +       y1="9"
    +       x2="10"
    +       y2="14"
    +       id="linearGradient4547"
    +       xlink:href="#linearGradient4374"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4507"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(0,2)" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4505"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-2,-1)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="12"
    +       y2="10"
    +       id="linearGradient4503"
    +       xlink:href="#linearGradient4310"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="12"
    +       y2="12"
    +       id="linearGradient4501"
    +       xlink:href="#linearGradient4328"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="6"
    +       y1="5"
    +       x2="10"
    +       y2="7"
    +       id="linearGradient4499"
    +       xlink:href="#linearGradient4302"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="6"
    +       x2="10"
    +       y2="9"
    +       id="linearGradient4497"
    +       xlink:href="#linearGradient4320"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="11"
    +       x2="4"
    +       y2="5"
    +       id="linearGradient4495"
    +       xlink:href="#linearGradient4294"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4493"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(4,0)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4491"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="5"
    +       x2="16"
    +       y2="9"
    +       id="linearGradient4489"
    +       xlink:href="#linearGradient4336"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10.0625"
    +       y1="8.03125"
    +       x2="12"
    +       y2="11"
    +       id="linearGradient4487"
    +       xlink:href="#linearGradient4344"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="16"
    +       y2="12"
    +       id="linearGradient4485"
    +       xlink:href="#linearGradient4366"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="16"
    +       y2="14"
    +       id="linearGradient4483"
    +       xlink:href="#linearGradient4382"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="4"
    +       y1="9"
    +       x2="10"
    +       y2="14"
    +       id="linearGradient4481"
    +       xlink:href="#linearGradient4374"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4438"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(0,2)" />
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4415"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(-2,-1)" />
    +    <linearGradient
    +       id="linearGradient4392-6">
    +      <stop
    +         id="stop4394-2"
    +         style="stop-color:#000000;stop-opacity:0.17195767"
    +         offset="0" />
    +      <stop
    +         id="stop4396-8"
    +         style="stop-color:#000000;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       x1="13"
    +       y1="8"
    +       x2="8"
    +       y2="9"
    +       id="linearGradient4390-0"
    +       xlink:href="#linearGradient4392-6"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="16"
    +       y2="14"
    +       id="linearGradient4380"
    +       xlink:href="#linearGradient4382"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="4"
    +       y1="9"
    +       x2="10"
    +       y2="14"
    +       id="linearGradient4372"
    +       xlink:href="#linearGradient4374"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="16"
    +       y2="12"
    +       id="linearGradient4364"
    +       xlink:href="#linearGradient4366"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4362"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse"
    +       gradientTransform="translate(4,0)" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="10"
    +       y2="11"
    +       id="linearGradient4352"
    +       xlink:href="#linearGradient4354"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10.0625"
    +       y1="8.03125"
    +       x2="12"
    +       y2="11"
    +       id="linearGradient4350"
    +       xlink:href="#linearGradient4344"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="5"
    +       x2="16"
    +       y2="9"
    +       id="linearGradient4342"
    +       xlink:href="#linearGradient4336"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="10"
    +       y1="9"
    +       x2="12"
    +       y2="12"
    +       id="linearGradient4326"
    +       xlink:href="#linearGradient4328"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="6"
    +       x2="10"
    +       y2="9"
    +       id="linearGradient4318"
    +       xlink:href="#linearGradient4320"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="8"
    +       x2="12"
    +       y2="10"
    +       id="linearGradient4316"
    +       xlink:href="#linearGradient4310"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="6"
    +       y1="5"
    +       x2="10"
    +       y2="7"
    +       id="linearGradient4308"
    +       xlink:href="#linearGradient4302"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       x1="8"
    +       y1="11"
    +       x2="4"
    +       y2="5"
    +       id="linearGradient4300"
    +       xlink:href="#linearGradient4294"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       id="linearGradient4294">
    +      <stop
    +         id="stop4296"
    +         style="stop-color:#008e00;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4298"
    +         style="stop-color:#00d300;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4302">
    +      <stop
    +         id="stop4304"
    +         style="stop-color:#0fff00;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4306"
    +         style="stop-color:#0fba00;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4310">
    +      <stop
    +         id="stop4312"
    +         style="stop-color:#19ff00;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4314"
    +         style="stop-color:#19a800;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4320">
    +      <stop
    +         id="stop4322"
    +         style="stop-color:#0f8400;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4324"
    +         style="stop-color:#0fba00;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4328">
    +      <stop
    +         id="stop4330"
    +         style="stop-color:#197600;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4332"
    +         style="stop-color:#19a800;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4336">
    +      <stop
    +         id="stop4338"
    +         style="stop-color:#ffff00;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4340"
    +         style="stop-color:#b7b400;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4344">
    +      <stop
    +         id="stop4346"
    +         style="stop-color:#929100;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4348"
    +         style="stop-color:#c4c400;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4354">
    +      <stop
    +         id="stop4356"
    +         style="stop-color:#616000;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4358"
    +         style="stop-color:#bfbf00;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4366">
    +      <stop
    +         id="stop4368"
    +         style="stop-color:#ff0000;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4370"
    +         style="stop-color:#630000;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4374">
    +      <stop
    +         id="stop4376"
    +         style="stop-color:#dc0000;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4378"
    +         style="stop-color:#9a0000;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient4382">
    +      <stop
    +         id="stop4384"
    +         style="stop-color:#370000;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop4386"
    +         style="stop-color:#ff0000;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient3763">
    +      <stop
    +         id="stop3765"
    +         style="stop-color:#0080ff;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop3767"
    +         style="stop-color:#005bb6;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient3769">
    +      <stop
    +         id="stop3771"
    +         style="stop-color:#003060;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop3773"
    +         style="stop-color:#0060c0;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient3775">
    +      <stop
    +         id="stop3777"
    +         style="stop-color:#004992;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop3779"
    +         style="stop-color:#0062c4;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       id="linearGradient3781">
    +      <stop
    +         id="stop3783"
    +         style="stop-color:#003060;stop-opacity:1"
    +         offset="0" />
    +      <stop
    +         id="stop3785"
    +         style="stop-color:#0060c0;stop-opacity:1"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       x1="6"
    +       y1="8"
    +       x2="4"
    +       y2="5"
    +       id="linearGradient4240"
    +       xlink:href="#linearGradient3870"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       id="linearGradient3870">
    +      <stop
    +         id="stop3872"
    +         style="stop-color:#000000;stop-opacity:0.52200001"
    +         offset="0" />
    +      <stop
    +         id="stop3874"
    +         style="stop-color:#000000;stop-opacity:0.169"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       x1="8"
    +       y1="6"
    +       x2="10"
    +       y2="9"
    +       id="linearGradient4242"
    +       xlink:href="#linearGradient3876"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       id="linearGradient3876">
    +      <stop
    +         id="stop3878"
    +         style="stop-color:#000000;stop-opacity:0.47799999"
    +         offset="0" />
    +      <stop
    +         id="stop3880"
    +         style="stop-color:#000000;stop-opacity:0.27000001"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       x1="6"
    +       y1="5"
    +       x2="10"
    +       y2="7"
    +       id="linearGradient4244"
    +       xlink:href="#linearGradient3864"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       id="linearGradient3864">
    +      <stop
    +         id="stop3866"
    +         style="stop-color:#000000;stop-opacity:0"
    +         offset="0" />
    +      <stop
    +         id="stop3868"
    +         style="stop-color:#000000;stop-opacity:0.26972011"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       x1="6"
    +       y1="8"
    +       x2="4"
    +       y2="5"
    +       id="linearGradient4246"
    +       xlink:href="#linearGradient3870"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       id="linearGradient4291">
    +      <stop
    +         id="stop4293"
    +         style="stop-color:#000000;stop-opacity:0.52200001"
    +         offset="0" />
    +      <stop
    +         id="stop4295"
    +         style="stop-color:#000000;stop-opacity:0.169"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       x1="8"
    +       y1="6"
    +       x2="10"
    +       y2="9"
    +       id="linearGradient4248"
    +       xlink:href="#linearGradient3876"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       id="linearGradient4298">
    +      <stop
    +         id="stop4300"
    +         style="stop-color:#000000;stop-opacity:0.47799999"
    +         offset="0" />
    +      <stop
    +         id="stop4302"
    +         style="stop-color:#000000;stop-opacity:0.27000001"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       x1="6"
    +       y1="5"
    +       x2="10"
    +       y2="7"
    +       id="linearGradient4250"
    +       xlink:href="#linearGradient3864"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       id="linearGradient4305">
    +      <stop
    +         id="stop4307"
    +         style="stop-color:#000000;stop-opacity:0"
    +         offset="0" />
    +      <stop
    +         id="stop4309"
    +         style="stop-color:#000000;stop-opacity:0.26972011"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       x1="6"
    +       y1="8"
    +       x2="4"
    +       y2="5"
    +       id="linearGradient4252"
    +       xlink:href="#linearGradient3870"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       id="linearGradient4312">
    +      <stop
    +         id="stop4314-7"
    +         style="stop-color:#000000;stop-opacity:0.52200001"
    +         offset="0" />
    +      <stop
    +         id="stop4316"
    +         style="stop-color:#000000;stop-opacity:0.169"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       x1="8"
    +       y1="6"
    +       x2="10"
    +       y2="9"
    +       id="linearGradient4254-9"
    +       xlink:href="#linearGradient3876"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       id="linearGradient4319">
    +      <stop
    +         id="stop4321"
    +         style="stop-color:#000000;stop-opacity:0.47799999"
    +         offset="0" />
    +      <stop
    +         id="stop4323"
    +         style="stop-color:#000000;stop-opacity:0.27000001"
    +         offset="1" />
    +    </linearGradient>
    +    <linearGradient
    +       x1="6"
    +       y1="5"
    +       x2="10"
    +       y2="7"
    +       id="linearGradient4256"
    +       xlink:href="#linearGradient3864"
    +       gradientUnits="userSpaceOnUse" />
    +    <linearGradient
    +       id="linearGradient4326-4">
    +      <stop
    +         id="stop4328"
    +         style="stop-color:#000000;stop-opacity:0"
    +         offset="0" />
    +      <stop
    +         id="stop4330-6"
    +         style="stop-color:#000000;stop-opacity:0.26972011"
    +         offset="1" />
    +    </linearGradient>
    +  </defs>
    +  <g
    +     transform="translate(-1,-1036.3622)"
    +     id="layer1">
    +    <image
    +       xlink:href="../nuvola/16x16/folder_yellow.png"
    +       x="1"
    +       y="1036.3622"
    +       width="16"
    +       height="16"
    +       id="image2998" />
    +    <g
    +       transform="translate(4,1039.3622)"
    +       id="g4209">
    +      <path
    +         d="m 6.5,5.5 -2,1 0,2 2,1 0,2 2,1 2,-1 0,-2 2,-1 0,-2 -2,-1 -2,1 -2,-1 z"
    +         id="path4080"
    +         style="fill:none;stroke:#000000;stroke-opacity:1" />
    +      <g
    +         id="g4180">
    +        <g
    +           id="g4032">
    +          <g
    +             transform="translate(-0.2419352,-4.2903229)"
    +             id="g3882">
    +            <g
    +               transform="translate(-2,-1)"
    +               id="g3884">
    +              <path
    +                 d="m 8.7419355,10.790323 -2,1 0,2 2,1 1.9999995,-1 0,-2 -1.9999995,-1 z"
    +                 id="path3886"
    +                 style="fill:#00ff00;fill-opacity:1;stroke:none" />
    +            </g>
    +          </g>
    +          <g
    +             transform="translate(0.5,1.5)"
    +             id="g3847">
    +            <g
    +               transform="translate(-2,-1)"
    +               id="g3849">
    +              <path
    +                 d="M 4,5 4,7 6,8 6,6 4,5 z"
    +                 transform="translate(2,1)"
    +                 id="path3851"
    +                 style="fill:url(#linearGradient4240);fill-opacity:1;stroke:none" />
    +              <path
    +                 d="M 10,6 8,7 8,9 10,8 10,6 z"
    +                 id="path3853"
    +                 style="fill:url(#linearGradient4242);fill-opacity:1;stroke:none" />
    +              <path
    +                 d="M 10,6 8,7 6,6 8,5 10,6 z"
    +                 id="path3855"
    +                 style="fill:url(#linearGradient4244);fill-opacity:1;stroke:none" />
    +            </g>
    +          </g>
    +        </g>
    +        <g
    +           transform="translate(-1,0)"
    +           id="g4042">
    +          <g
    +             transform="translate(4.7580647,-4.290323)"
    +             id="g3935"
    +             style="fill:#0080ff;fill-opacity:1">
    +            <g
    +               transform="translate(-2,-1)"
    +               id="g3937"
    +               style="fill:#0080ff;fill-opacity:1">
    +              <path
    +                 d="m 8.7419355,10.790323 -2,1 0,2 2,1 1.9999995,-1 0,-2 -1.9999995,-1 z"
    +                 id="path3939"
    +                 style="fill:#0080ff;fill-opacity:1;stroke:none" />
    +            </g>
    +          </g>
    +          <g
    +             transform="translate(5.5,1.5)"
    +             id="g3941">
    +            <g
    +               transform="translate(-2,-1)"
    +               id="g3943">
    +              <path
    +                 d="M 4,5 4,7 6,8 6,6 4,5 z"
    +                 transform="translate(2,1)"
    +                 id="path3945"
    +                 style="fill:url(#linearGradient4246);fill-opacity:1;stroke:none" />
    +              <path
    +                 d="M 10,6 8,7 8,9 10,8 10,6 z"
    +                 id="path3947"
    +                 style="fill:url(#linearGradient4248);fill-opacity:1;stroke:none" />
    +              <path
    +                 d="M 10,6 8,7 6,6 8,5 10,6 z"
    +                 id="path3949"
    +                 style="fill:url(#linearGradient4250);fill-opacity:1;stroke:none" />
    +            </g>
    +          </g>
    +        </g>
    +        <g
    +           transform="translate(-0.3225806,-1.2741937)"
    +           id="g4052">
    +          <g
    +             transform="translate(2.0806454,-0.0161293)"
    +             id="g3965"
    +             style="fill:#ff0000;fill-opacity:1">
    +            <g
    +               transform="translate(-2,-1)"
    +               id="g3967"
    +               style="fill:#ff0000;fill-opacity:1">
    +              <path
    +                 d="m 8.7419355,10.790323 -2,1 0,2 2,1 1.9999995,-1 0,-2 -1.9999995,-1 z"
    +                 id="path3969"
    +                 style="fill:#ff0000;fill-opacity:1;stroke:none" />
    +            </g>
    +          </g>
    +          <g
    +             transform="translate(2.8225806,5.7741937)"
    +             id="g3971">
    +            <g
    +               transform="translate(-2,-1)"
    +               id="g3973">
    +              <path
    +                 d="M 4,5 4,7 6,8 6,6 4,5 z"
    +                 transform="translate(2,1)"
    +                 id="path3975"
    +                 style="fill:url(#linearGradient4252);fill-opacity:1;stroke:none" />
    +              <path
    +                 d="M 10,6 8,7 8,9 10,8 10,6 z"
    +                 id="path3977"
    +                 style="fill:url(#linearGradient4254-9);fill-opacity:1;stroke:none" />
    +              <path
    +                 d="M 10,6 8,7 6,6 8,5 10,6 z"
    +                 id="path3979"
    +                 style="fill:url(#linearGradient4256);fill-opacity:1;stroke:none" />
    +            </g>
    +          </g>
    +        </g>
    +      </g>
    +    </g>
    +  </g>
    +</svg>
    
  • GPL/Icons/ModifiedNuvola/closedSmallFolder.svg+0 0 added
  • GPL/Icons/ModifiedNuvola/dataTypes.svg+1305 0 added
  • GPL/Icons/ModifiedNuvola/disabledClosedFolder.svg+1259 0 added
  • GPL/Icons/ModifiedNuvola/disabledOpenFolder.svg+1259 0 added
  • GPL/Icons/ModifiedNuvola/openFolderArchive.svg+151 0 added
  • GPL/Icons/ModifiedNuvola/openFolderCheckedOut.svg+189 0 added
  • GPL/Icons/ModifiedNuvola/openFolderClasses.svg+158 0 added
  • GPL/Icons/ModifiedNuvola/openFolderExternals.svg+201 0 added
  • GPL/Icons/ModifiedNuvola/openFolderFunctions.svg+223 0 added
  • GPL/Icons/ModifiedNuvola/openFolderGroup.svg+1144 0 added
  • GPL/Icons/ModifiedNuvola/openFolderInView.svg+1262 0 added
  • GPL/Icons/ModifiedNuvola/openFolderLabels.svg+1274 0 added
  • GPL/Icons/ModifiedNuvola/openFolderNamespaces.svg+1287 0 added
  • GPL/Icons/ModifiedNuvola/openFolder.svg+150 0 added
  • GPL/Icons/ModifiedNuvola/openProject.svg+1371 0 added
  • GPL/Icons/ModifiedNuvola/openSmallFolder.svg+1246 0 added
  • GPL/licenses/certification.local.manifest+8 0 added
  • GPL/licenses/GPL_2_With_Classpath_Exception.txt+352 0 added
  • GPL/licenses/GPL_3.html+697 0 added
  • GPL/licenses/GPL_3_Linking_Permitted.txt+5 0 added
  • GPL/licenses/LGPL_2.1.txt+504 0 added
  • GPL/licenses/LGPL_3.0.html+517 0 added
  • GPL/licenses/Modified_Nuvola_Icons_-_LGPL_2.1.txt+2 0 added
  • GPL/licenses/Public_Domain.txt+1 0 added
  • GPL/nativeBuildProperties.gradle+182 0 added
  • GPL/settings.gradle+4 0 added
45377acb5bcd

Merge 3e2f5418847a41776996cb4a90450d3b400d97cf into 505a59ff3e2491e12b5a11c124325481adde38a7

https://github.com/nationalsecurityagency/ghidrajro-califApr 8, 2026via body-scan-shorthand
1 file changed · +8 8
  • Ghidra/Features/GhidraServer/src/main/java/ghidra/server/security/PKIAuthenticationModule.java+8 8 modified
    @@ -141,14 +141,14 @@ public String authenticate(UserManager userMgr, Subject subject, Callback[] call
     			DefaultTrustManagerFactory.validateClient(certChain, PKIUtils.RSA_TYPE);
     
     			byte[] sigBytes = sigCb.getSignature();
    -			if (sigBytes != null) {
    -
    -				Signature sig = Signature.getInstance(certChain[0].getSigAlgName());
    -				sig.initVerify(certChain[0]);
    -				sig.update(token);
    -				if (!sig.verify(sigBytes)) {
    -					throw new FailedLoginException("Incorrect signature");
    -				}
    +			if (sigBytes == null) {
    +				throw new FailedLoginException("Client signature required");
    +			}
    +			Signature sig = Signature.getInstance(certChain[0].getSigAlgName());
    +			sig.initVerify(certChain[0]);
    +			sig.update(token);
    +			if (!sig.verify(sigBytes)) {
    +				throw new FailedLoginException("Incorrect signature");
     			}
     
     			String dnUsername =
    

Vulnerability mechanics

Root cause

"The PKIAuthenticationModule.authenticate() method improperly handles certificate signatures, allowing impersonation."

Attack vector

An attacker with a valid CA-signed certificate can bypass authentication by presenting their public certificate with a null signature to the Ghidra server. This allows them to impersonate any user, leading to privilege escalation, modification of repository access controls, exfiltration of sensitive data, and potential server compromise. The vulnerability is exploitable over the network without requiring user interaction.

Affected code

The vulnerability resides within the `PKIAuthenticationModule.authenticate()` method. The provided patches modify files related to PKI framework support, including changes in `ghidra.net.ApplicationKeyManagerUtils` and `ghidra.net.SSLContextInitializer` to use new utility classes [ref_id=1].

What the fix does

The patches refactor the PKI framework support by replacing usages of `ApplicationKeyManagerUtils` and `SSLContextInitializer` with `PKIUtils` and `DefaultSSLContextInitializer` respectively [patch_id=5478756, patch_id=5478757, patch_id=5478758]. This change likely addresses the underlying issue in how certificates and trust are managed, preventing the improper handling of null signatures during authentication.

Preconditions

  • authAttacker must possess a valid CA-signed certificate.

Generated on Jun 10, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

4

News mentions

1