/* * Print out the usage information for just the options. */ static void printOptionUsage( tOptions* pOpts, int ex_code, tCC* pOptTitle ) { int ct = pOpts->optCt; int optNo = 0; tOptDesc* pOD = pOpts->pOptDesc; int docCt = 0; do { if ((pOD->fOptState & OPTST_OMITTED) != 0) continue; if ((pOD->fOptState & OPTST_DOCUMENT) != 0) { if (ex_code == EXIT_SUCCESS) { fprintf(option_usage_fp, argTypes.pzBrk, pOD->pzText, pOptTitle); docCt++; } continue; } /* * IF this is the first auto-opt maintained option * *AND* we are doing a full help * *AND* there are documentation options * *AND* the last one was not a doc option, * THEN document that the remaining options are not user opts */ if ( (pOpts->presetOptCt == optNo) && (ex_code == EXIT_SUCCESS) && (docCt > 0) && ((pOD[-1].fOptState & OPTST_DOCUMENT) == 0) ) fprintf( option_usage_fp, argTypes.pzBrk, zAuto, pOptTitle ); printOneUsage( pOpts, pOD, &argTypes ); /* * IF we were invoked because of the --help option, * THEN print all the extra info */ if (ex_code == EXIT_SUCCESS) printExtendedUsage( pOpts, pOD, &argTypes ); } while (pOD++, optNo++, (--ct > 0)); fputc( '\n', option_usage_fp ); }
int main (int argc, char **argv) { // start flags declarations... gDataOffset = 0; //globally declared in GCMutils.h; Must be initialized before use... int hexFlag = 0; //for extracting: char *extractFileFrom = NULL; char *extractFileTo = NULL; char *fsReplacePath = NULL; verboseFlag = 0; int showInfoFlag = 1; int extractDiskHeaderFlag = 0; char *extractDiskHeaderFile = GCM_DISK_HEADER_FILENAME; int extractDiskHeaderInfoFlag = 0; char *extractDiskHeaderInfoFile = GCM_DISK_HEADER_INFO_FILENAME; int extractApploaderFlag = 0; char *extractApploaderFile = GCM_APPLOADER_FILENAME; int extractBootDolFlag = 0; char *extractBootDolFile = GCM_BOOT_DOL_FILENAME; int injectDiskHeaderFlag = 0; char *injectDiskHeaderFile = GCM_DISK_HEADER_FILENAME; int injectDiskHeaderInfoFlag = 0; char *injectDiskHeaderInfoFile = GCM_DISK_HEADER_INFO_FILENAME; int injectApploaderFlag = 0; char *injectApploaderFile = GCM_APPLOADER_FILENAME; char *replaceFileLocalPath = NULL; char *replaceFileGCMPath = NULL; int listFilesFlag = 0; listInfoFlag = 0; listPathFlag = 0; // end flag declarations //start argument parsing... char *currentArg = NULL; do { currentArg = GET_NEXT_ARG; if (!currentArg) { //there's no args! uh oh! //printf("No arguments...\n"); printUsage(); exit(0); } else if (CHECK_ARG(ARG_VERBOSE)) { //turn on verbosity! verboseFlag++; verbosePrint("Verbose output ON."); } else if (CHECK_ARG(ARG_HELP)) { // print extended help printExtendedUsage(); exit(0); } else if (CHECK_ARG(ARG_INFO)) { //they want to see info... showInfoFlag++; verbosePrint("Show info flag ON."); } else if (CHECK_ARG(ARG_HEX)) { //they want hex notation... hexFlag = 1; verbosePrint("Hex notation ON."); } else if (CHECK_ARG(ARG_OFFSET)) { //change the data offset gDataOffset = strtoul(GET_NEXT_ARG, NULL, 0); char verboseMsg[32] = ""; sprintf(verboseMsg, "Data offset changed to: %d", gDataOffset); verbosePrint(verboseMsg); } else if (CHECK_ARG(ARG_REPLACE_FILESYSTEM)) { // they want to replace the filesystem fsReplacePath = GET_NEXT_ARG; if (!fsReplacePath) { printf("Argument error...\n"); printUsage(); exit(1); } } else if (CHECK_ARG(ARG_EXTRACT)) { // extract files... // usage: -e <path> <destPath> extractFileFrom = GET_NEXT_ARG; extractFileTo = GET_NEXT_ARG; if (!extractFileFrom || !extractFileTo) { //argument error... something was omitted... printf("Argument error.\n"); printUsage(); exit(1); } } else if (CHECK_ARG(ARG_EXTRACT_DISK_HEADER)) { // extract disk header... (to a file called "boot.bin") extractDiskHeaderFlag++; if (PEEK_ARG && strcmp(PEEK_ARG, OPT_FILE) == 0) { // if they're specifying a file... SKIP_NARG(1); //skip that -f we just looked at... extractDiskHeaderFile = GET_NEXT_ARG; } } else if (CHECK_ARG(ARG_EXTRACT_DISK_HEADER_INFO)) { // extract disk header info... (to a file called "bi2.bin") extractDiskHeaderInfoFlag++; if (PEEK_ARG && strcmp(PEEK_ARG, OPT_FILE) == 0) { // if they're specifying a file... SKIP_NARG(1); //skip that -f we just looked at... extractDiskHeaderInfoFile = GET_NEXT_ARG; } } else if (CHECK_ARG(ARG_EXTRACT_APPLOADER)) { //extract apploader... (to a file called "appldr.bin") extractApploaderFlag++; if (PEEK_ARG && strcmp(PEEK_ARG, OPT_FILE) == 0) { // if they're specifying a file... SKIP_NARG(1); //skip that -f we just looked at... extractApploaderFile = GET_NEXT_ARG; } } else if (CHECK_ARG(ARG_EXTRACT_BOOT_DOL)) { //extract the boot dol... extractBootDolFlag++; if (PEEK_ARG && strcmp(PEEK_ARG, OPT_FILE) == 0) { //if they specify a file... SKIP_NARG(1); //skip that -f extractBootDolFile = GET_NEXT_ARG; } } else if (CHECK_ARG(ARG_INJECT_DISK_HEADER)) { //inject the diskheader injectDiskHeaderFlag++; if (PEEK_ARG && strcmp(PEEK_ARG, OPT_FILE) == 0) { //if they're specifying a file... (otherwise use the default); SKIP_NARG(1); //skip the -f we just looked at... injectDiskHeaderFile = GET_NEXT_ARG; } } else if (CHECK_ARG(ARG_INJECT_DISK_HEADER_INFO)) { //inject the diskheaderinfo... injectDiskHeaderInfoFlag++; if (PEEK_ARG && strcmp(PEEK_ARG, OPT_FILE) == 0) { // if they're specifying a file... SKIP_NARG(1); injectDiskHeaderInfoFile = GET_NEXT_ARG; } } else if (CHECK_ARG(ARG_INJECT_APPLOADER)) { //inject the apploader... injectApploaderFlag++; if (PEEK_ARG && strcmp(PEEK_ARG, OPT_FILE) == 0) { //if they're specifying a file... SKIP_NARG(1); injectApploaderFile = GET_NEXT_ARG; } } else if (CHECK_ARG(ARG_REPLACE_FILE)) { //they want to replace a file... replaceFileGCMPath = GET_NEXT_ARG; replaceFileLocalPath = GET_NEXT_ARG; if (!replaceFileGCMPath || !replaceFileLocalPath) { printf("Argument error!\n"); printUsage(); exit(1); } } else if (CHECK_ARG(ARG_LIST)) { // list filesystem listFilesFlag++; //turn the listFiles flag on. while(1) { if (PEEK_ARG && (strcmp(PEEK_ARG, OPT_FILE_INFO) == 0 || strcmp(PEEK_ARG, OPT_FILE_INFO_SYN) == 0)) { SKIP_NARG(1); listInfoFlag++; } else if (PEEK_ARG && (strcmp(PEEK_ARG, OPT_FULL_PATH) == 0 || strcmp(PEEK_ARG, OPT_FULL_PATH_SYN) == 0)) { SKIP_NARG(1); listPathFlag++; } else { break; } } } else { // do it to this file... this is the last argument... just ignore the rest... filepath = currentArg; filename = lastPathComponent(filepath); break; } } while(*argv); //end parsing arguments... //open the file for reading and start doing read operations! openFile("r"); // print the info... if (showInfoFlag) { printGCMInfo(hexFlag); } // list the files, if necesary... if (listFilesFlag) { listFiles(); } // extract files... if (extractFileFrom && extractFileTo) { //testing recursive extraction... GCMFileEntryStruct *e = NULL; if (strcmp(extractFileFrom, "/") == 0) { e = GCMGetRootFileEntry(gcmFile); printf("root file entry index: %d\n", e->index); } else { e = GCMGetFileEntryAtPath(gcmFile, extractFileFrom); } strcpy(extractRootPath, extractFileTo); recurseFileEntry(e, extractFileEntry); free(e); //extractFile(extractFileFrom, extractFileTo); } //extract diskheader if (extractDiskHeaderFlag) { extractDiskHeader(extractDiskHeaderFile); } //extract diskheaderinfo if (extractDiskHeaderInfoFlag) { extractDiskHeaderInfo(extractDiskHeaderInfoFile); } //extract apploader if (extractApploaderFlag) { extractApploader(extractApploaderFile); } //extract main executable DOL if (extractBootDolFlag) { extractBootDol(extractBootDolFile); } //close the file and open it again for read/write closeFile(); openFile("r+"); //inject the diskheader if (injectDiskHeaderFlag) { injectDiskHeader(injectDiskHeaderFile); } //inject the diskheaderinfo if (injectDiskHeaderInfoFlag) { injectDiskHeaderInfo(injectDiskHeaderInfoFile); } //inject the apploader if (injectApploaderFlag) { injectApploader(injectApploaderFile); } if (replaceFileLocalPath && replaceFileGCMPath) { replaceFile(replaceFileGCMPath, replaceFileLocalPath); } //replace the filesystem if (fsReplacePath) { GCMReplaceFilesystem(gcmFile, fsReplacePath); } closeFile(); return 0; }
int main(int argc, char **argv) { char *newName = NULL; char *newDeveloper = NULL; char *newFullName = NULL; char *newFullDeveloper = NULL; char *newDescription = NULL; char *extractIconPath = NULL; char *injectIconPath = NULL; int modIndex = 0; int extractFormat = RAW_FORMAT; int injectFormat = RAW_FORMAT; char *currentArg = NULL; do { currentArg = GET_NEXT_ARG; if (!currentArg) { //eek, there's no arg! must be an argument error... print usage... printUsage(); exit(1); } else if (CHECK_ARG(ARG_HELP)) { //they want the extended usage, so print it and bail... printExtendedUsage(); exit(1); } else if (CHECK_ARG(ARG_MOD_NTH)) { //they only want the nth record to be printed... modIndex = atoi(GET_NEXT_ARG); if (modIndex < 1) { printf(" index is out of bounds! (%d)\n", modIndex); exit(1); } } else if (CHECK_ARG(ARG_SET_NAME)) { //they want to set the name... if (PEEK_ARG) { //if there is a next argument... newName = GET_NEXT_ARG; } } else if (CHECK_ARG(ARG_SET_DEVELOPER)) { //they want to set the developer... if (PEEK_ARG) { //if there's a next argument newDeveloper = GET_NEXT_ARG; } } else if (CHECK_ARG(ARG_SET_FULL_NAME)) { //the want to set the full name if (PEEK_ARG) { //if there's a next argument newFullName = GET_NEXT_ARG; } } else if (CHECK_ARG(ARG_SET_FULL_DEVELOPER)) { //they want to set the full developer if (PEEK_ARG) { //if there's a next argument newFullDeveloper = GET_NEXT_ARG; } } else if (CHECK_ARG(ARG_SET_DESCRIPTION)) { //they want to set the description... if (PEEK_ARG) { //if there's a next argument newDescription = GET_NEXT_ARG; } } else if (CHECK_ARG(ARG_GET_ICON)) { //they want to extract the icon if (PEEK_ARG) { //make sure there's at least one more argument if (strcmp(PEEK_ARG, OPT_FORMAT_RAW) == 0) { extractFormat = RAW_FORMAT; SKIP_NARG(1); } else if (strcmp(PEEK_ARG, OPT_FORMAT_PPM) == 0) { extractFormat = PPM_FORMAT; SKIP_NARG(1); } if (PEEK_ARG) { extractIconPath = GET_NEXT_ARG; } } } else if (CHECK_ARG(ARG_SET_ICON)) { //they want to inject the icon... if (PEEK_ARG) { //make sure there's at least one more argument... if (strcmp(PEEK_ARG, OPT_FORMAT_RAW) == 0) { injectFormat = RAW_FORMAT; SKIP_NARG(1); } else if (strcmp(PEEK_ARG, OPT_FORMAT_PPM) == 0) { injectFormat = PPM_FORMAT; SKIP_NARG(1); } if (PEEK_ARG) { injectIconPath = GET_NEXT_ARG; } } } else { //if the argument doesn't fit anything else... it must be the filename. // set the filename and stop looping... start processing! filename = currentArg; break; } }while (*argv); openBnr(); //read the file into a buffer... unsigned long len = GetFilesizeFromStream(bnrFile); char *data = (char*)malloc(len); if (ReadDataFromFile(data, filename) != len) { perror(filename); exit(1); } GCMBnrStruct *b = GCMRawBnrToStruct(data, len); if (!b) { printf("error opening banner!\n"); exit(1); } printBnr(b); int fileChanged = 0; GCMBnrInfoStruct *mod = NULL; if (b->version != '1') { mod = GCMBnrGetNthInfo(b->info, modIndex - 1); } else { mod = b->info; } if (!mod) { printf("ERROR! mod == NULL (this shouldn't happen!)\n"); exit(1); } if (newName != NULL) { //let's set the name... bzero(mod->name, GCM_BNR_GAME_NAME_LENGTH); strcpy(mod->name, newName); fileChanged = 1; } if (newDeveloper != NULL) { //let's set the developer... bzero(mod->developer, GCM_BNR_DEVELOPER_LENGTH); strcpy(mod->developer, newDeveloper); fileChanged = 1; } if (newFullName != NULL) { bzero(mod->fullName, GCM_BNR_FULL_TITLE_LENGTH); strcpy(mod->fullName, newFullName); fileChanged = 1; } if (newFullDeveloper != NULL) { bzero(mod->fullDeveloper, GCM_BNR_FULL_DEVELOPER_LENGTH); strcpy(mod->fullDeveloper, newFullDeveloper); fileChanged = 1; } if (newDescription != NULL) { bzero(mod->description, GCM_BNR_DESCRIPTION_LENGTH); strcpy(mod->description, newDescription); fileChanged = 1; } if (extractIconPath != NULL) { char *imageData = NULL; u32 len; if (extractFormat == RAW_FORMAT) { //if we're extracting to a .raw file... (default) len = GCM_BNR_GRAPHIC_RAW_FILE_LENGTH; imageData = (char*)malloc(len); GCMBnrGetImageRaw(b, imageData); } else { //if we're extracting to a .ppm file... len = GCM_BNR_GRAPHIC_PPM_FILE_LENGTH; imageData = (char*)malloc(len); GCMBnrGetImagePPM(b, imageData); } WriteDataToFile(imageData, len, extractIconPath); } if (injectIconPath != NULL) { //printf("going to inject...\n"); u32 len = GetFilesizeFromPath(injectIconPath); char *imageData = (char*)malloc(len); if (injectFormat == RAW_FORMAT) { //if the file we're injecting is in raw format (default) if (ReadDataFromFile(imageData, injectIconPath) != len) { perror(injectIconPath); exit(1); } } else { //if the file we're injecting is in ppm format... //this isn't implemented yet... so tell the user and bail printf("PPM IMPORT IS NOT IMPLEMENTED! (file not affected)\n\n"); exit(1); } char *iconData = (char*)malloc(GCM_BNR_GRAPHIC_DATA_LENGTH); GCMBnrRawImageToGraphic(imageData, iconData); memcpy(b->graphic, iconData, GCM_BNR_GRAPHIC_DATA_LENGTH); free(iconData); fileChanged = 1; } if (fileChanged) { //printf("Writing bnr file...\n"); rewind(bnrFile); u32 bnrSize = GCMBnrRawSize(b); char *buf = (char*)malloc(bnrSize); GCMBnrStructToRaw(b, buf); if (fwrite(buf, 1, bnrSize, bnrFile) != bnrSize) { perror(filename); //printf("error writing to bnr! (%s)\n", filename); exit(1); } } GCMFreeBnrInfoStruct(b->info); closeBnr(); return 0; }