mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 02:09:44 +02:00
Candidate release of source code.
This commit is contained in:
parent
db81e6b3b0
commit
79d8f164f8
12449 changed files with 2800756 additions and 16 deletions
|
@ -0,0 +1,244 @@
|
|||
/* ###
|
||||
* 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.
|
||||
*/
|
||||
// Script upgrades all Program files within the current project.
|
||||
// Since there should be no checkouts when an upgrade is performed,
|
||||
// the script will optionally list any existing checkouts prior to starting
|
||||
// the batch upgrade.
|
||||
//
|
||||
//@category Upgrade
|
||||
import java.io.IOException;
|
||||
|
||||
import ghidra.app.script.GhidraScript;
|
||||
import ghidra.framework.client.ClientUtil;
|
||||
import ghidra.framework.client.RepositoryAdapter;
|
||||
import ghidra.framework.data.CheckinHandler;
|
||||
import ghidra.framework.model.*;
|
||||
import ghidra.framework.store.ItemCheckoutStatus;
|
||||
import ghidra.program.database.ProgramContentHandler;
|
||||
import ghidra.program.model.lang.LanguageNotFoundException;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.exception.VersionException;
|
||||
|
||||
public class RepositoryFileUpgradeScript extends GhidraScript {
|
||||
|
||||
boolean includePrivatePrograms;
|
||||
|
||||
@Override
|
||||
protected void run() throws Exception {
|
||||
RepositoryAdapter repository = null;
|
||||
try {
|
||||
Project project = state.getProject();
|
||||
if (project == null) {
|
||||
popup("No active project found!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentProgram != null) {
|
||||
popup("All programs must be closed before running this script!");
|
||||
return;
|
||||
}
|
||||
|
||||
repository = project.getRepository();
|
||||
if (repository != null && !repository.isConnected()) {
|
||||
if (askYesNo("Connect?",
|
||||
"You are not connected to the repository server! Connect now?")) {
|
||||
repository.connect();
|
||||
if (!repository.isConnected()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
popup("Operation cancelled - unable to proceed without connected repository.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ProjectData projectData = project.getProjectData();
|
||||
if (askYesNo("Find Active Checkouts?",
|
||||
"Would you like to query the repository for active checkouts before attempting upgrade?")) {
|
||||
int count = listCheckouts(projectData.getRootFolder());
|
||||
if (count == 0) {
|
||||
if (!askYesNo("Continue?",
|
||||
"Would you like to continue with Program file upgrades?")) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!askYesNo("Checkouts Found! Continue?",
|
||||
count + " checkouts were found and have been listed in the script log.\n" +
|
||||
"Checked-out files will be skipped during batch upgrade.\n \n" +
|
||||
"Would you like to continue with Program file upgrades?")) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
includePrivatePrograms = askYesNo("Upgrade Option",
|
||||
"Would you like to include private local files in upgrade?");
|
||||
|
||||
int count = performProgramUpgrades(projectData.getRootFolder());
|
||||
popup(count + " Program files were upgraded");
|
||||
}
|
||||
catch (CancelledException e) {
|
||||
popup(getClass().getSimpleName() + " execution cancelled.");
|
||||
}
|
||||
catch (Exception e) {
|
||||
String operation = getClass().getSimpleName() + " execution";
|
||||
ClientUtil.handleException(repository, e, operation, null);
|
||||
}
|
||||
}
|
||||
|
||||
private int listCheckouts(DomainFolder folder) throws IOException, CancelledException {
|
||||
int count = 0;
|
||||
for (DomainFile df : folder.getFiles()) {
|
||||
monitor.checkCanceled();
|
||||
count += listCheckouts(df);
|
||||
}
|
||||
for (DomainFolder subfolder : folder.getFolders()) {
|
||||
monitor.checkCanceled();
|
||||
count += listCheckouts(subfolder);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
private int listCheckouts(DomainFile df) throws IOException {
|
||||
if (!df.isVersioned()) {
|
||||
return 0;
|
||||
}
|
||||
int count = 0;
|
||||
for (ItemCheckoutStatus checkout : df.getCheckouts()) {
|
||||
++count;
|
||||
String loc = checkout.getUser() + "@" + checkout.getProjectPath();
|
||||
println("Active checkout: " + df.getPathname() + " (" + loc + ")");
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
private int performProgramUpgrades(DomainFolder folder) throws IOException, CancelledException {
|
||||
int count = 0;
|
||||
for (DomainFile df : folder.getFiles()) {
|
||||
monitor.checkCanceled();
|
||||
if (performProgramUpgrade(df)) {
|
||||
++count;
|
||||
}
|
||||
}
|
||||
for (DomainFolder subfolder : folder.getFolders()) {
|
||||
monitor.checkCanceled();
|
||||
count += performProgramUpgrades(subfolder);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
private boolean performProgramUpgrade(DomainFile df) throws IOException, CancelledException {
|
||||
if (!ProgramContentHandler.PROGRAM_CONTENT_TYPE.equals(df.getContentType())) {
|
||||
return false;
|
||||
}
|
||||
boolean versionedFile = df.isVersioned();
|
||||
if (!versionedFile && !includePrivatePrograms) {
|
||||
return false;
|
||||
}
|
||||
if (df.isReadOnly()) {
|
||||
printerr("Skipping read-only file: " + df.getPathname());
|
||||
return false;
|
||||
}
|
||||
if (df.isCheckedOut()) {
|
||||
printerr("Skipping locally checked-out file: " + df.getPathname());
|
||||
return false;
|
||||
}
|
||||
if (versionedFile && !df.checkout(true, monitor)) {
|
||||
printerr("Failed to get exclusive checkout for file: " + df.getPathname());
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean upgraded = false;
|
||||
try {
|
||||
upgraded = upgradeProgram(df);
|
||||
}
|
||||
catch (LanguageNotFoundException e) {
|
||||
printerr("Skipping file (" + e.getMessage() + "): " + df.getPathname());
|
||||
return false;
|
||||
}
|
||||
catch (VersionException e) {
|
||||
printerr("Program created with newer/unknown Ghidra version: " + df.getPathname());
|
||||
return false;
|
||||
}
|
||||
finally {
|
||||
if (versionedFile) {
|
||||
df.undoCheckout(false);
|
||||
}
|
||||
}
|
||||
return upgraded;
|
||||
}
|
||||
|
||||
private boolean upgradeProgram(DomainFile df)
|
||||
throws VersionException, CancelledException, IOException {
|
||||
|
||||
try {
|
||||
// Check if upgrade is needed and is possible
|
||||
DomainObject dobj = df.getDomainObject(this, false, false, monitor);
|
||||
dobj.release(this);
|
||||
return false; // no upgrade needed
|
||||
}
|
||||
catch (VersionException e) {
|
||||
if (!e.isUpgradable()) {
|
||||
throw e; // upgrade not possible
|
||||
}
|
||||
}
|
||||
|
||||
boolean upgraded = false;
|
||||
DomainObject dobj = df.getDomainObject(this, true, false, monitor);
|
||||
try {
|
||||
if (dobj.isChanged()) {
|
||||
dobj.save("Batch Upgrade", monitor);
|
||||
dobj.release(this);
|
||||
dobj = null;
|
||||
if (df.isVersioned()) {
|
||||
df.checkin(checkinHandler, false, monitor);
|
||||
println("Repository file upgraded: " + df.getPathname());
|
||||
}
|
||||
else {
|
||||
println("Local file upgraded: " + df.getPathname());
|
||||
}
|
||||
upgraded = true;
|
||||
}
|
||||
}
|
||||
finally {
|
||||
if (dobj != null) {
|
||||
dobj.release(this);
|
||||
}
|
||||
}
|
||||
return upgraded;
|
||||
}
|
||||
|
||||
CheckinHandler checkinHandler = new CheckinHandler() {
|
||||
|
||||
@Override
|
||||
public boolean keepCheckedOut() throws CancelledException {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getComment() throws CancelledException {
|
||||
return "Batch Upgrade";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean createKeepFile() throws CancelledException {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue