home *** CD-ROM | disk | FTP | other *** search
- //----------------------------------------------------------------------------------------------------
- //
- // 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;
- int openStatus;
- id windowList = [NXApp windowList];
- id libExtractionsFileViewer = nil;
- id appListener = NXResponsibleDelegate ([NXApp appListener], @selector(openFile:ok:));
-
- 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
- [appListener openFile: EXTRACTION_FOLDER ok: &openStatus];
-
- 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