This is LibInspector.m in view mode; [Download] [Up]
//---------------------------------------------------------------------------------------------------- // // LibInspector // // Inherits From: WMInspector // // Declared In: LibInspector.h // // Disclaimer // // You may freely copy, distribute and reuse this software and its // associated documentation. I disclaim any warranty of any kind, // expressed or implied, as to its fitness for any particular use. // //---------------------------------------------------------------------------------------------------- #import "LibInspector.h" #define AR_TV "ar tv" #define AR_X "ar x" #define CD "cd" #define MKDIR "mkdir" #define EXTRACTION_FOLDER "/tmp/LibExtractions" #define OUT_OF_MEMORY "Out of Memory!" #define MKDIR_ERROR "Unable to create temporary folder!" #define PROCESS_ERROR "Unable to open process stream!" #define PARSE_ERROR "Unable to recognize library information!" #define MAX_AR_FILENAME_LEN 16 static FILE* responseStream; @implementation LibInspector static id _SELF = nil; //---------------------------------------------------------------------------------------------------- // Private Methods //---------------------------------------------------------------------------------------------------- - _alert: (STR) errorMessage { NXRunAlertPanel (NULL, "%s", NULL, NULL, NULL, errorMessage); return self; } - _getTableOfContents { // Get library's table of contents by sending AR_TV command. // Response stream will be read to populate browser (in brower:fillMatrix:inColumn). STR command; char currentPath [MAXPATHLEN+1]; [self selectionPathsInto:currentPath separator:'\0']; if (! (command = malloc (strlen (AR_TV) + strlen (currentPath) + 2))) { [self _alert: OUT_OF_MEMORY]; return nil; } sprintf (command, "%s %s", AR_TV, currentPath); if (! (responseStream = popen (command, "r"))) { if (command) free (command); [self _alert: PROCESS_ERROR]; return nil; } if (command) free (command); return self; } - (BOOL)_createLibExtractionFolder { // Make a temporary directory for extractions (EXTRACTION_FOLDER). // Return YES if exists/successful, NO if error. STR command; struct stat statBuffer; if (stat (EXTRACTION_FOLDER, &statBuffer) == 0) return YES; if (! (command = malloc (strlen (MKDIR) + strlen (EXTRACTION_FOLDER) + 2))) { [self _alert: OUT_OF_MEMORY]; return NO; } sprintf (command, "%s %s", MKDIR, EXTRACTION_FOLDER); system (command); if (stat (EXTRACTION_FOLDER, &statBuffer) != 0) { if (command) free (command); [self _alert: MKDIR_ERROR]; return NO; } if (command) free (command); return YES; } - _openLibExtractionsFileViewer { // Search the application's windowList for the LibExtractions FileViewer. // Open the window if it exists, open a new one if not. This will prevent // multiple FileViewers from being displayed. int iterator; id windowList = [NXApp windowList]; id libExtractionsFileViewer = nil; for (iterator = 0; iterator < [windowList count]; iterator++) if (NXOrderStrings ([[windowList objectAt:iterator] title], "LibExtractions", YES, strlen ("LibExtractions"), NULL) == 0) libExtractionsFileViewer = [windowList objectAt:iterator]; if (libExtractionsFileViewer) if ([libExtractionsFileViewer style] == NX_MINIWINDOWSTYLE) [libExtractionsFileViewer deminiaturize:nil]; else [libExtractionsFileViewer makeKeyAndOrderFront:nil]; else [[Application workspace] selectFile: EXTRACTION_FOLDER inFileViewerRootedAt: EXTRACTION_FOLDER]; return self; } - _extractSelectedFiles { // Extract selected files into a temporary folder and open that folder. id selectionList = [browser getSelectedCells: nil]; int iterator; STR command; STR filename; char currentPath [MAXPATHLEN+1]; if ([selectionList count]) if (! [self _createLibExtractionFolder]) return nil; [self selectionPathsInto: currentPath separator:'\0']; if (! (command = malloc (strlen (CD) + strlen (EXTRACTION_FOLDER) + strlen (AR_X) + MAXPATHLEN + MAX_AR_FILENAME_LEN + 10))) { [self _alert: OUT_OF_MEMORY]; return nil; } for (iterator = 0; iterator < [selectionList count]; iterator++) { filename = NXCopyStringBuffer ([[selectionList objectAt: iterator] stringValue]); if (! (filename = strtok (filename, " \t\n"))) { if (command) free (command); return nil; } sprintf (command, "%s %s; %s %s %s", CD, EXTRACTION_FOLDER, AR_X, currentPath, filename); system (command); if (filename) free (filename); } [self _openLibExtractionsFileViewer]; if (command) free (command); return self; } - (STR)_format: (STR)responseLine { // Parse and format the response line. Where a token gets memcpy'd within the // formatString indicates its position within the displayed string. Have to exclude // some information. Also, throw out names beginning with '__.'. These are archive // table names, header stuff, etc., (or possibly very weird file names). Returns a // formatted string that the caller must free, or some error condition. // (example response line) "rw-r--r-- 0/1 4572 Jul 29 23:53 1992 NXImage.o". STR currentToken; char formatString[51]; memset (formatString, ' ', 50); formatString [50] = '\0'; if (! strtok (responseLine, " \t")) return PARSE_ERROR; if (! strtok (NULL, " \t")) return PARSE_ERROR; if (! (currentToken = strtok (NULL, " \t\n"))) return PARSE_ERROR; memcpy (formatString + 18, currentToken, strlen (currentToken)); if (! (currentToken = strtok (NULL, " \t\n"))) return PARSE_ERROR; memcpy (formatString + 26, currentToken, strlen (currentToken)); if (! (currentToken = strtok (NULL, " \t\n"))) return PARSE_ERROR; memcpy (formatString + 30, currentToken, strlen (currentToken)); if (! (currentToken = strtok (NULL, " \t\n"))) return PARSE_ERROR; if (! (currentToken = strtok (NULL, " \t\n"))) return PARSE_ERROR; memcpy (formatString + 33, currentToken, strlen (currentToken)); if (! (currentToken = strtok (NULL, " \t\n"))) return PARSE_ERROR; memcpy (formatString, currentToken, strlen (currentToken)); if (NXOrderStrings (currentToken, "__.", NO, 3, NULL) == 0) return NULL; return NXCopyStringBuffer (formatString); } //---------------------------------------------------------------------------------------------------- // WMInspector Methods //---------------------------------------------------------------------------------------------------- + new { // Required/called by WM. Only allow one instance... char path[MAXPATHLEN+1]; id bundle; if (_SELF) return _SELF; _SELF = self = [super new]; if ( ! (bundle = [NXBundle bundleForClass:[LibInspector class]] ) ) return nil; if ( ! [bundle getPath:path forResource:"LibInspector" ofType:"nib"] ) return nil; [NXApp loadNibFile:path owner:self withNames:NO fromZone:[self zone]]; return _SELF; } - revert: sender { // Called by WM when file selection is type we inspect. [self _getTableOfContents]; [[[self okButton] setTitle: "Extract"] setIconPosition: NX_TITLEONLY]; [browser loadColumnZero]; return [super revert: sender]; } - ok:sender { // User pressed 'Extract' button... [self _extractSelectedFiles]; return [super ok:sender]; } //---------------------------------------------------------------------------------------------------- // Action Methods //---------------------------------------------------------------------------------------------------- - browserClicked: sender { // A file or files have been selected in the browser. Enable 'Extract' // button if not an empty selection. if ([browser selectedCell]) [[self okButton] setEnabled: YES]; else [[self okButton] setEnabled: NO]; return self; } //---------------------------------------------------------------------------------------------------- // Browser Delegate Method //---------------------------------------------------------------------------------------------------- - (int) browser: aBrowser fillMatrix: aMatrix inColumn: (int)aColumn { // Populate Table Of Contents browser with formatted command response. // Set the font for the browser text here (fixed font for even column alignment). // Minimal error checking within read loop - NULL indicates an entry we want // to skip (like an archive header), PARSE_ERROR indicates a response that // could not be recognized, all else are considered successful. id font = [Font newFont: "Courier" size: 10]; int count = 0; char nextLine [81]; STR formattedLine; while (fgets (nextLine, 999, responseStream)) { if ( (formattedLine = [self _format: nextLine]) == NULL) continue; if ( NXOrderStrings (formattedLine, PARSE_ERROR, YES, -1, NULL) == 0) { [self _alert: PARSE_ERROR]; break; } [aMatrix renewRows: (count+1) cols: 1]; [[aMatrix cellAt: count :0] setFont: font]; [[aMatrix cellAt: count :0] setStringValue: formattedLine]; [[[aMatrix cellAt: count :0] setLoaded: YES] setLeaf: YES]; if (formattedLine) free (formattedLine); count++; } if (font) [font free]; pclose (responseStream); return count; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.