home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <stdlib.h>
- #include <console.h>
- #include <unix.h>
- #include <StandardFile.h>
- #include <Files.h>
- #include <Dialogs.h>
-
- typedef unsigned char uchar;
- typedef unsigned short ushort;
- typedef unsigned long ulong;
-
- #define NAMESIZE 100
-
- typedef struct
- {
- char name[NAMESIZE];
- char mode[8];
- char uid[8];
- char gid[8];
- char size[12];
- char mtime[12];
- char checksum[8];
- char link[NAMESIZE+2];
- char extno[4];
- char exttotal[4];
- char efsize[12];
- } FileInfo;
-
- #define DIGIT(x) ('0' <= (x) && (x) <= '7')
- #define VALUE(x) ((x) - '0')
-
- char block[ 512 ];
-
- int listflag = 1;
-
- ulong readnum( char * dp, int maxsize );
- void main( int argc, char ** argv );
- void HiliteDefault( DialogPtr d );
-
- ulong readnum( char * dp, int maxsize )
- {
- ulong answer = 0;
-
- while ( ! DIGIT(*dp) && --maxsize > 0 )
- dp++;
- while ( DIGIT(*dp) && maxsize-- > 0 )
- answer = answer * 8 + VALUE(*dp++);
- return answer;
- }
-
- void main( int argc, char ** argv )
- {
- int i, j;
- long size;
- int dflag;
- FileInfo * fp;
- char * ep;
- HParamBlockRec h;
- Handle kirk;
- extern long _fcreator;
- Point p;
- SFReply reply;
- OSErr err;
- FILE * in;
- DialogPtr dp;
- char tempstr[33];
- long templ;
- int itemType, itemHit;
- Handle item;
- Rect itemRect;
- int forceFlag = 0;
- int convertFlag = 0;
-
- kirk = GetResource( 'KIRK', 128 );
- _fcreator = **(long **)kirk;
-
-
- printf("\n\n" );
- printf( "Simple tar extraction utility, version 1.0, by Tim Smith.\n" );
- printf( "This program and its source code are in the public domain.\n" );
- printf( "\n" );
- printf( "Follow the instructions that will be displayed at the bottom\n" );
- printf( "of this window for each dialog that is displayed.\n" );
-
- dp = GetNewDialog( 128, 0, (WindowPtr)-1 );
-
- StartOver:
- printf( "\n========================================\n" );
- printf( "Select a tar archive.\n" );
- fflush( stdout );
- p.h = 200;
- p.v = 50;
- SFGetFile( p, 0, 0, -1, 0, 0, &reply );
-
- if ( reply.good == TRUE )
- {
- PtoCstr( reply.fName );
- err = SetVol( 0, reply.vRefNum );
- if ( err )
- {
- printf( "ERROR: could not set directory!\n" );
- fflush( stdout );
- goto StartOver;
- }
- in = fopen( (char *)reply.fName, "rb" );
- if ( in == NULL )
- {
- printf( "ERROR: could not open file!\n" );
- fflush( stdout );
- goto StartOver;
- }
- }
- else
- ExitToShell();
-
- fp = (FileInfo *)block;
-
- RedoDialog:
- printf( "\n========================================\n" );
- printf( "Archive is %s.\n", reply.fName );
- printf( "\n" );
- printf( "Press LIST to get a listing of the files in the archive. They will be\n" );
- printf( "listed with their Unix name (e.g., '/' between components of a path).\n" );
- printf( "\n" );
- printf( "Press EXTRACT to extract all of the files in the archive. Directories\n" );
- printf( "will be created as needed.\n" );
- printf( "\n" );
- printf( "Press CANCEL to return to the file selection dialog.\n" );
- printf( "\n" );
- printf( "Set the creator to use for extracted files in the text edit box, and\n" );
- printf( "control conversion of text files from Unix to Mac format with the check\n" );
- printf( "box. The default creator is in the KIRK 128 resource, by the way.\n" );
- fflush( stdout );
- GetDItem( dp, 4, &itemType, &item, &itemRect );
- tempstr[0] = 4;
- tempstr[1] = _fcreator >> 24;
- tempstr[2] = _fcreator >> 16;
- tempstr[3] = _fcreator >> 8;
- tempstr[4] = _fcreator;
- SetIText( item, tempstr );
-
- GetDItem( dp, 5, &itemType, &item, &itemRect );
- SetCtlValue( item, 1 );
-
- ShowWindow( dp );
- SelectWindow( dp );
- SelIText( dp, 4, 0, -1 );
-
- do
- {
- HiliteDefault( dp );
- ModalDialog( 0, &itemHit );
- if ( itemHit == 5 )
- {
- GetDItem( dp, 5, &itemType, &item, &itemRect );
- SetCtlValue( item, 1 - GetCtlValue(item) );
- }
- }
- while ( itemHit != 1 && itemHit != 2 && itemHit != 3 );
-
- GetDItem( dp, 5, &itemType, &item, &itemRect );
- convertFlag = GetCtlValue(item);
-
- HideWindow( dp );
-
- if ( itemHit == 3 )
- {
- fclose( in );
- goto StartOver;
- }
-
- GetDItem( dp, 4, &itemType, &item, &itemRect );
- GetIText( item, tempstr );
- if ( tempstr[0] != 4 )
- {
- printf( "ERROR: creator set to bogus value! It must be exactly four\n" );
- printf( " four characters. Try again." );
- fflush( stdout );
- goto RedoDialog;
- }
- _fcreator = tempstr[1];
- _fcreator <<= 8;
- _fcreator |= tempstr[2] & 0xff;
- _fcreator <<= 8;
- _fcreator |= tempstr[3] & 0xff;
- _fcreator <<= 8;
- _fcreator |= tempstr[4] & 0xff;
-
- if ( itemHit == 2 )
- listflag = 1;
- else
- listflag = 0;
-
- printf( "\n\n\n" );
-
- size = 0;
- forceFlag = 0;
- fseek( in, 0, SEEK_SET );
- while ( 1 )
- {
- if ( fread( block, 512, 1, in ) != 1 )
- break;
- if ( fp->name[0] == '\0' )
- {
- break;
- }
- size = readnum( fp->size, 12 );
- for ( i = 0; i < NAMESIZE; i++ )
- if ( fp->name[i] == '\0' )
- break;
- if ( forceFlag == 0 )
- {
- for ( j = 0; j < i; j++ )
- {
- if ( fp->name[j] < ' ' || fp->name[j] > 127 )
- {
- printf( "\nERROR: bad character in file name.\n" );
- if ( StopAlert( 129, 0 ) == 2 )
- {
- forceFlag = 1;
- break;
- }
- else
- goto StartOver;
- }
- }
- }
- if ( i && fp->name[i-1] == '/' && size == 0 )
- {
- printf( "DIRECTORY %s\n", fp->name );
- if ( ! listflag )
- {
- int err;
- uchar mname[128];
-
- mname[0] = 1;
- mname[1] = ':';
- if ( fp->name[0] == '/' )
- i = 1;
- else
- i = 0;
- for ( ; fp->name[i] != '\0'; i++ )
- {
- if ( fp->name[i] == '/' )
- fp->name[i] = ':';
- mname[++mname[0]] = fp->name[i];
- }
- if ( mname[mname[0]] == ':' && mname[0] > 1 )
- mname[0]--;
- mname[1+mname[0]] = '\0';
- h.fileParam.ioCompletion = 0;
- h.fileParam.ioNamePtr = mname;
- h.fileParam.ioVRefNum = 0;
- h.fileParam.ioDirID = 0;
- err = PBDirCreate( &h, 0 );
- if ( err )
- {
- printf( "ERROR: creation of directory failed!\n" );
- goto StartOver;
- }
- }
- continue;
- }
- else if ( fp->link[0] && size == 0 )
- {
- printf( "WARNING: %s was linked to %s. Ignored\n", fp->name, &fp->link[1] );
- continue;
- }
- else
- printf( "%s, %ld bytes\n", fp->name, size );
-
- if ( ! listflag )
- {
- FILE * wp;
- int c;
- int pad;
- char mname[128];
-
- mname[0] = ':';
- if ( fp->name[0] == '/' )
- i = 1;
- else
- i = 0;
- for ( c = 1; fp->name[i] != '\0'; i++ )
- {
- if ( fp->name[i] == '/' )
- fp->name[i] = ':';
- mname[c++] = fp->name[i];
- }
- mname[c] ='\0';
-
- pad = (512 - (size % 512)) % 512;
- wp = fopen( mname, "wb" );
- if ( wp == NULL )
- {
- printf( "ERROR: could not create!...skipping\n" );
- goto skipall;
- }
- while ( size-- > 0 )
- {
- c = getc(in);
- if ( c == 0x0A && convertFlag )
- c = 0x0D;
- putc(c,wp);
- }
-
- while ( pad-- > 0 )
- getc(in);
- fclose(wp);
- }
- else
- {
- if ( ! listflag )
- printf( "---unnamed file skipped\n" );
- skipall:
- size += 511; size /= 512;
-
- while ( size-- > 0 )
- {
- if ( fread( block, 512, 1, in ) != 1 )
- break;
- }
- if ( size >= 0 )
- {
- printf( "ERROR: read failed or unexpected end of file.\n" );
- break;
- }
- }
- }
- printf( "%s complete.\n", listflag ? "Listing" : "Extraction" );
- fflush( stdout );
- if ( listflag )
- goto RedoDialog;
- else
- goto StartOver;
- }
-
- void HiliteDefault( DialogPtr d )
- {
- int ItemType;
- Handle Item;
- Rect ItemRect;
-
- GrafPtr savePort;
-
- GetPort( &savePort );
- SetPort( d );
-
- GetDItem( d, 1, &ItemType, &Item, &ItemRect );
- InsetRect( &ItemRect, -4, -4 );
- PenSize( 3, 3 );
- FrameRoundRect( &ItemRect, 16, 16 );
-
- SetPort( savePort );
- }
-
-