1 module updater; 2 3 import filemanager; 4 import nspire; 5 import nspire.device; 6 import std.stdio; 7 import std.string; 8 import std.file; 9 import std.format; 10 import std.path; 11 import std.zip; 12 13 int updaterFun(NSpire nspire, DeviceInfo deviceInfo, string[] args) { 14 writeln("NSpire Tools - Operating System Updater\n"); 15 16 if (args.length < 1) { 17 writeln("Usage: nspire-tools updater <operating system image path>"); 18 writeln("\tor: nspire-updater <operating system image path>\n"); 19 return 1; 20 } 21 22 writeln("\033[1mWARNING: Updating your operating system may cause a permanent hard brick"); 23 writeln("of your TI-NSpire, always check what you are doing\033[22m"); 24 writeln(); 25 writeln(); 26 27 if (!checkExtOs(deviceInfo, args[0])) { 28 return ErrorCodes.NSPIRE_ERR_INVALID; 29 } 30 31 if (!args[0].exists || !args[0].isFile) { 32 writeln(args[0], " is not a valid file"); 33 return ErrorCodes.NSPIRE_ERR_INVALID; 34 } 35 36 writeln("Update file: ", args[0].absolutePath); 37 writeln("Update size: ", args[0].getSize); 38 39 void[] fileBuf; 40 ZipArchive zip; 41 string manifest; 42 43 try { 44 fileBuf = read(args[0]); 45 } catch (FileException e) { 46 writeln("Error: failed file read on local side"); 47 return ErrorCodes.NSPIRE_ERR_INVALID; 48 } 49 50 try { 51 zip = new ZipArchive(fileBuf); 52 } catch (ZipException e) { 53 writeln(args[0], " is not a valid file"); 54 return ErrorCodes.NSPIRE_ERR_INVALID; 55 } 56 57 if (("manifest.txt" in zip.directory) is null) { 58 writeln(args[0], " is not a valid file"); 59 return ErrorCodes.NSPIRE_ERR_INVALID; 60 } 61 62 try { 63 manifest = (cast(char[]) zip.expand(zip.directory["manifest.txt"])).dup; 64 } catch (ZipException e) { 65 writeln(args[0], " is not a valid file"); 66 return ErrorCodes.NSPIRE_ERR_INVALID; 67 } 68 69 auto updateVersion = manifest.splitLines[1].strip; 70 auto currentVersion = format!"%u.%u.%u"(deviceInfo.versionOs.major, deviceInfo.versionOs.minor, deviceInfo.versionOs.build); 71 72 writeln("Update OS version: ", updateVersion); 73 writeln("Current OS version: ", currentVersion); 74 75 if (updateVersion == currentVersion) { 76 writeln("\033[1mWarning: you have already installed this update!\033[22m"); 77 } 78 79 writeln(); 80 writeln("\033[1mDuring the update, make sure not to disconnect the USB cable and not turn off the computer!\033[22m"); 81 writeln("\033[1mIf you are using a laptop connected to the power supply before continue.\033[22m"); 82 writeln(); 83 write("Enter the version of the OS you want to update to confirm the start of the updater: "); 84 auto checkVersion = stdin.readln.strip; 85 86 if (checkVersion != updateVersion) { 87 writeln("Error: Update process aborted, user check failed!"); 88 return ErrorCodes.NSPIRE_ERR_INVALID; 89 } 90 91 writeln(); 92 writeln("\033[1mUpdate in progress (it takes a long time)... DO NOT DISCONNECT THE USB CABLE OR TURN OFF THE COMPUTER\033[22m"); 93 auto error = nspire.sendOs(fileBuf); 94 writeln(); 95 96 if (error != ErrorCodes.NSPIRE_ERR_SUCCESS) { 97 writeln("Error: ", NSpire.errorStr(error)); 98 writeln("\033[1mAn An error in the update process can have serious consequences,\033[22m"); 99 writeln("\033[1mAn make sure you understand what happened before taking any action\033[22m"); 100 101 return error; 102 } 103 104 writeln("\033[1mUpdate successful! Your NSpire is restarting with the OS version ", updateVersion, "\033[22m"); 105 return 0; 106 }