From 65e164f81d909d55f234225f482445bc4e35adba Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Wed, 9 Dec 1998 22:24:27 +0000 Subject: [PATCH] Removing the BeOS specific 'ar' utility -- no longer needed, says Chris Herborth. --- BeOS/ar-1.1/Makefile | 48 --- BeOS/ar-1.1/README.html | 1 - BeOS/ar-1.1/README.txt | 29 -- BeOS/ar-1.1/ar | Bin 16355 -> 0 bytes BeOS/ar-1.1/ar.xMAP | 461 --------------------- BeOS/ar-1.1/commands.c | 809 ------------------------------------- BeOS/ar-1.1/commands.h | 28 -- BeOS/ar-1.1/copy_attrs.c | 128 ------ BeOS/ar-1.1/copy_attrs.h | 24 -- BeOS/ar-1.1/docs/ar.html | 234 ----------- BeOS/ar-1.1/docs/dumpar.py | 271 ------------- BeOS/ar-1.1/docs/dumpo.py | 126 ------ BeOS/ar-1.1/docs/notes | 34 -- BeOS/ar-1.1/main.c | 312 -------------- BeOS/ar-1.1/mwlib.c | 711 -------------------------------- BeOS/ar-1.1/mwlib.h | 118 ------ 16 files changed, 3334 deletions(-) delete mode 100644 BeOS/ar-1.1/Makefile delete mode 100644 BeOS/ar-1.1/README.html delete mode 100644 BeOS/ar-1.1/README.txt delete mode 100644 BeOS/ar-1.1/ar delete mode 100644 BeOS/ar-1.1/ar.xMAP delete mode 100644 BeOS/ar-1.1/commands.c delete mode 100644 BeOS/ar-1.1/commands.h delete mode 100644 BeOS/ar-1.1/copy_attrs.c delete mode 100644 BeOS/ar-1.1/copy_attrs.h delete mode 100644 BeOS/ar-1.1/docs/ar.html delete mode 100644 BeOS/ar-1.1/docs/dumpar.py delete mode 100644 BeOS/ar-1.1/docs/dumpo.py delete mode 100644 BeOS/ar-1.1/docs/notes delete mode 100644 BeOS/ar-1.1/main.c delete mode 100644 BeOS/ar-1.1/mwlib.c delete mode 100644 BeOS/ar-1.1/mwlib.h diff --git a/BeOS/ar-1.1/Makefile b/BeOS/ar-1.1/Makefile deleted file mode 100644 index 8fb11ec023dc..000000000000 --- a/BeOS/ar-1.1/Makefile +++ /dev/null @@ -1,48 +0,0 @@ -###################################################################### -# Makefile for ar -# -# Dec. 14, 1997 Chris Herborth (chrish@kagi.com) -# -# $Id$ -###################################################################### - -AR_VERSION=1.1 - -# Make variables -CC=mwcc -LD=mwcc - -CFLAGS=-w9 -rostr -O3 -g -CFLAGS_O=-w9 -rostr -O7 -opt schedule604 -LDFLAGS=-g -map ar.xMAP -LDFLAGS_O= - -INSTALL=install -m 755 - -DESTINATION=/boot/home/config/bin - -PARTS=main.o mwlib.o commands.o copy_attrs.o - -all: ar - -nodebug: - -rm -f ar $(PARTS) ar.dbg ar.xSYM - $(MAKE) CFLAGS="$(CFLAGS_O) -DNO_DEBUG" LDFLAGS="$(LDFLAGS_O)" ar - -ar: $(PARTS) - $(LD) $(LDFLAGS) -o $@ $(PARTS) - -install: ar - $(INSTALL) ar $(DESTINATION) - ln -sf $(DESTINATION)/ar $(DESTINATION)/ar-posix - -clean: - -rm -f $(PARTS) ar ar.dbg ar.xSYM - -zip: - (cd .. ; zip -9ry ar-$(AR_VERSION).zip ar-$(AR_VERSION) \ - -x ar-$(AR_VERSION)/RCS -x ar-$(AR_VERSION)/docs/RCS \ - -x ar-$(AR_VERSION)/RCS/\* -x ar-$(AR_VERSION)/docs/RCS/\*) - -%.o: %.c - $(CC) $(CFLAGS) -c $< -o $@ diff --git a/BeOS/ar-1.1/README.html b/BeOS/ar-1.1/README.html deleted file mode 100644 index 607c03a08bf0..000000000000 --- a/BeOS/ar-1.1/README.html +++ /dev/null @@ -1 +0,0 @@ -docs/ar.html \ No newline at end of file diff --git a/BeOS/ar-1.1/README.txt b/BeOS/ar-1.1/README.txt deleted file mode 100644 index f99578962984..000000000000 --- a/BeOS/ar-1.1/README.txt +++ /dev/null @@ -1,29 +0,0 @@ -ar - POSIX 1003.2 interface to library files - -Here's the source and PowerPC binary for a POSIX 1003.2 interface "ar" -command; this is extremely useful when you're porting complex UNIX/POSIX -software to BeOS for PowerPC (I originally wrote it to support my Python -port). - -To build/install ar, do this in a Terminal: - -make nodebug install - -This will create ar and ar-posix (a symlink to ar) in ~/config/bin. The -ar-posix symlink is to make things a little easier if you happen to -have GeekGadgets (see www.ninemoons.com) installed; it comes with an -ar that only works on objects/libraries produced by GNU C for BeOS. - -To use the POSIX ar with your port, do something like this: - -AR=ar-posix ./configure ... normal configure arguments ... - -and then: - -make AR=ar-posix - -You may need to check the Makefiles; people seem to be quite sloppy about -using just plain "ar cr libfoo.a ..." instead of "$(AR) cr libfoo.a ...". - -- Chris Herborth, April 18, 1998 - (chrish@kagi.com) diff --git a/BeOS/ar-1.1/ar b/BeOS/ar-1.1/ar deleted file mode 100644 index e44e2dc4c228de7ffb000ab701d80b7d69748287..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc-jL100001 literal 16355 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 -#include -#ifndef NO_DEBUG -#include -#define ASSERT(cond) assert(cond) -#else -#define ASSERT(cond) ((void)0) -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "mwlib.h" -#include "commands.h" - -#ifndef FALSE -#define FALSE (0) -#endif -#ifndef TRUE -#define TRUE (!FALSE) -#endif - -static const char *rcs_version_id = "$Id$"; - -/* ---------------------------------------------------------------------- -** Local functions -** -** do_match() - find the index of the file, if it's in the archive; return -** TRUE if found, else FALSE -**/ -static int do_match( MWLib *lib, const char *file, int *idx ); - -static int do_match( MWLib *lib, const char *file, int *idx ) -{ - int which = 0; - char *name_ptr; - - ASSERT( lib != NULL ); - ASSERT( file != NULL ); - ASSERT( idx != NULL ); - - /* Skip over the path, if any, so we can compare just the file name. - */ - name_ptr = strrchr( file, '/' ); - if( name_ptr == NULL ) { - name_ptr = (char *)file; - } else { - name_ptr++; - } - - for( which = 0; which < lib->header.num_objects; which++ ) { - if( !strcmp( name_ptr, lib->names[which] ) ) { - *idx = which; - return TRUE; - } - } - - return FALSE; -} - -/* ---------------------------------------------------------------------- -** Delete an archive member. -** -** This isn't really optimal; you could make a more efficient version -** using a linked list instead of arrays for the data. This was easier -** to write, and speed shouldn't be that big a deal here... you're not -** likely to be dealing with thousands of files. -*/ -static status_t delete_lib_entry( MWLib *lib, int idx, int verbose ); - -status_t do_delete( const char *archive_name, char **files, int verbose ) -{ - status_t retval = B_OK; - MWLib lib; - int idx = 0; - int which = 0; - - ASSERT( archive_name != NULL ); - - if( files == NULL ) { - fprintf( stderr, "ar: %s, nothing to do\n", archive_name ); - return B_ERROR; - } - - retval = load_MW_lib( &lib, archive_name ); - if( retval != B_OK ) { - switch( retval ) { - case B_FILE_NOT_FOUND: - fprintf( stderr, "ar: %s, file not found\n", archive_name ); - return retval; - break; - - default: - return retval; - break; - } - } - - /* Delete the specified files. - */ - for( idx = 0; files[idx] != NULL; idx++ ) { - if( do_match( &lib, files[idx], &which ) ) { - retval = delete_lib_entry( &lib, which, verbose ); - } - which = 0; - } - - /* Write the new file. - */ - retval = write_MW_lib( &lib, archive_name ); - - return retval; -} - -static status_t delete_lib_entry( MWLib *lib, int which, int verbose ) -{ - uint32 new_num; - MWLibFile *new_files = NULL; - char **new_names = NULL; - char **new_data = NULL; - int ctr = 0; - int idx = 0; - - ASSERT( lib != NULL ); - ASSERT( which <= lib->header.num_objects ); - - new_num = lib->header.num_objects - 1; - - new_files = (MWLibFile *)malloc( new_num * ( sizeof( MWLibFile ) ) ); - new_names = (char **)malloc( new_num * ( sizeof( char * ) ) ); - new_data = (char **)malloc( new_num * ( sizeof( char * ) ) ); - if( new_files == NULL || new_names == NULL || new_data == NULL ) { - return B_NO_MEMORY; - } - - /* Copy the contents of the old lib to the new lib, skipping the one - ** we want to delete. - */ - for( ctr = 0; ctr < lib->header.num_objects; ctr++ ) { - if( ctr != which ) { - memcpy( &(new_files[idx]), &(lib->files[ctr]), - sizeof( MWLibFile ) ); - new_names[idx] = lib->names[ctr]; - new_data[idx] = lib->data[ctr]; - - idx++; - } else { - /* Free up the name and data. - */ - if( verbose ) { - printf( "d - %s\n", lib->names[ctr] ); - } - - free( lib->names[idx] ); - lib->names[idx] = NULL; - free( lib->data[idx] ); - lib->data[idx] = NULL; - } - } - - /* Free up the old lib's data. - */ - free( lib->files ); - free( lib->names ); - free( lib->data ); - - lib->files = new_files; - lib->names = new_names; - lib->data = new_data; - - lib->header.num_objects = new_num; - - return B_OK; -} - -/* ---------------------------------------------------------------------- -** Print an archive member to stdout. -*/ -static status_t print_lib_entry( MWLib *lib, int idx, int verbose ); - -status_t do_print( const char *archive_name, char **files, int verbose ) -{ - status_t retval = B_OK; - MWLib lib; - int idx = 0; - - ASSERT( archive_name != NULL ); - - retval = load_MW_lib( &lib, archive_name ); - if( retval != B_OK ) { - switch( retval ) { - case B_FILE_NOT_FOUND: - fprintf( stderr, "ar: %s, file not found\n", archive_name ); - return retval; - break; - - default: - return retval; - break; - } - } - - if( files == NULL ) { - /* Then we print the entire archive. - */ - for( idx = 0; idx < lib.header.num_objects; idx++ ) { - retval = print_lib_entry( &lib, idx, verbose ); - } - } else { - /* Then we print the specified files. - */ - int which = 0; - - for( idx = 0; files[idx] != NULL; idx++ ) { - if( do_match( &lib, files[idx], &which ) ) { - retval = print_lib_entry( &lib, which, verbose ); - } - which = 0; - } - } - - return retval; -} - -static status_t print_lib_entry( MWLib *lib, int idx, int verbose ) -{ - int recs; - - ASSERT( lib != NULL ); - - if( verbose ) { - printf( "\n<%s>\n\n", lib->names[idx] ); - } - - recs = fwrite( lib->data[idx], lib->files[idx].object_size, 1, stdout ); - fflush( stdout ); - if( recs != 1 ) { - fprintf( stderr, "error printing %s, %s\n", lib->names[idx], - strerror( errno ) ); - return B_OK; - } - - return B_OK; -} - -/* ---------------------------------------------------------------------- -** Add/replace/update files in an archive. -*/ -static status_t add_lib_entry( MWLib *lib, const char *filename, int verbose ); -static status_t replace_lib_entry( MWLib *lib, const char *filename, - int idx, int verbose ); -static status_t load_lib_file( const char *filename, - char **data, MWLibFile *info ); - -static status_t load_lib_file( const char *filename, - char **data, MWLibFile *info ) -{ - status_t retval = B_OK; - struct stat s; - FILE *fp; - uint32 recs; - - ASSERT( filename != NULL ); - ASSERT( info != NULL ); - - /* Initialize the info area. - */ - info->m_time = (time_t)0; /* Only this... */ - info->off_filename = 0; - info->off_fullpath = 0; - info->off_object = 0; - info->object_size = 0; /* ... and this will actually be updated. */ - - /* stat() the file to get the info we need. - */ - retval = stat( filename, &s ); - if( retval != 0 ) { - fprintf( stderr, "ar: can't stat %s, %s\n", filename, - strerror( errno ) ); - return B_FILE_NOT_FOUND; - } - - /* Possible errors here; if you have an object that's larger - ** than a size_t can hold (malloc() can only allocate a size_t size, - ** not a full off_t)... - */ - if( s.st_size > (off_t)ULONG_MAX ) { - fprintf( stderr, "ar: %s is too large!\n", filename ); - return B_NO_MEMORY; - } - - /* Allocate enough memory to hold the file data. - */ - *data = (char *)malloc( (size_t)s.st_size ); - if( *data == NULL ) { - fprintf( stderr, "ar: can't allocate memory for %s\n", filename ); - return B_NO_MEMORY; - } - - /* Read the file's data. - */ - fp = fopen( filename, "r" ); - if( fp == NULL ) { - fprintf( stderr, "ar: can't open %s, %s\n", filename, - strerror( errno ) ); - retval = B_FILE_NOT_FOUND; - goto free_data_return; - } - - recs = fread( *data, (size_t)s.st_size, 1, fp ); - if( recs != 1 ) { - fprintf( stderr, "ar: can't read %s, %s\n", filename, - strerror( errno ) ); - retval = B_IO_ERROR; - goto close_fp_return; - } - - fclose( fp ); - - /* Now that all the stuff that can fail has succeeded, fill in the info - ** we need. - */ - info->m_time = s.st_mtime; - info->object_size = (uint32)s.st_size; - - return B_OK; - - /* How we should return if an error occurred. - */ -close_fp_return: - fclose( fp ); - -free_data_return: - free( *data ); - *data = NULL; - - return retval; -} - -status_t do_replace( const char *archive_name, char **files, int verbose, - int create, int update ) -{ - status_t retval = B_OK; - MWLib lib; - int idx = 0; - int which = 0; - - ASSERT( archive_name != NULL ); - - memset( &lib, 0, sizeof( MWLib ) ); - - if( files == NULL ) { - fprintf( stderr, "ar: %s, nothing to do\n", archive_name ); - return B_ERROR; - } - - retval = load_MW_lib( &lib, archive_name ); - if( retval != B_OK ) { - switch( retval ) { - case B_FILE_NOT_FOUND: - lib.header.magicword = 'MWOB'; - lib.header.magicproc = 'PPC '; - lib.header.magicflags = 0; - lib.header.version = 1; - - if( lib.files != NULL ) { - free( lib.files ); - lib.files = NULL; - } - - if( lib.names != NULL ) { - free( lib.names ); - lib.names = NULL; - } - - if( lib.data != NULL ) { - lib.data = NULL; - } - - if( !create ) { - fprintf( stderr, "ar: creating %s\n", archive_name ); - } - - if( update ) { - fprintf( stderr, "ar: nothing to do for %s\n", archive_name ); - return retval; - } - break; - - default: - return retval; - break; - } - } - - for( idx = 0; files[idx] != NULL; idx++ ) { - if( do_match( &lib, files[idx], &which ) ) { - /* Then the file exists, and we need to replace it or update it. - */ - if( update ) { - /* Compare m_times - ** then replace this entry - */ - struct stat s; - - retval = stat( files[idx], &s ); - if( retval != 0 ) { - fprintf( stderr, "ar: can't stat %s, %s\n", files[idx], - strerror( errno ) ); - } - - if( s.st_mtime >= lib.files[which].m_time ) { - retval = replace_lib_entry( &lib, files[idx], which, - verbose ); - } else { - fprintf( stderr, "ar: a newer %s is already in %s\n", - files[idx], archive_name ); - } - } else { - /* replace this entry - */ - retval = replace_lib_entry( &lib, files[idx], which, verbose ); - } - } else { - /* add this entry - */ - retval = add_lib_entry( &lib, files[idx], verbose ); - } - } - - /* Write the new file. - */ - retval = write_MW_lib( &lib, archive_name ); - - return retval; -} - -static status_t add_lib_entry( MWLib *lib, const char *filename, int verbose ) -{ - status_t retval = B_OK; - uint32 new_num_objects; - uint32 idx; - - ASSERT( lib != NULL ); - ASSERT( filename != NULL ); - - /* Find out how many objects we'll have after we add this one. - */ - new_num_objects = lib->header.num_objects + 1; - idx = lib->header.num_objects; - - /* Attempt to reallocate the MWLib's buffers. If one of these fails, - ** we could leak a little memory, but it shouldn't be a big deal in - ** a short-lived app like this. - */ - lib->files = (MWLibFile *)realloc( lib->files, - sizeof(MWLibFile) * new_num_objects ); - lib->names = (char **)realloc( lib->names, - sizeof(char *) * new_num_objects ); - lib->data = (char **)realloc( lib->data, - sizeof(char *) * new_num_objects ); - if( lib->files == NULL || lib->names == NULL || lib->data == NULL ) { - fprintf( stderr, "ar: can't allocate memory to add %s\n", filename ); - return B_NO_MEMORY; - } - - /* Load the file's data and info into the MWLib structure. - */ - retval = load_lib_file( filename, &(lib->data[idx]), &(lib->files[idx]) ); - if( retval != B_OK ) { - fprintf( stderr, "ar: error adding %s, %s\n", filename, - strerror( errno ) ); - - return retval; - } - - /* Save a copy of the filename. This is where we leak - ** sizeof(MWLibFile) + 2 * sizeof(char *) bytes because we don't - ** shrink lib->files, lib->names, and lib->data. - */ - lib->names[idx] = strdup( filename ); - if( lib->names == NULL ) { - fprintf( stderr, "ar: error allocating memory for filename\n" ); - - return B_NO_MEMORY; - } - - /* Now that everything's OK, we can update the MWLib header. - */ - lib->header.num_objects++; - - /* Give a little feedback. - */ - if( verbose ) { - printf( "a - %s\n", filename ); - } - - return B_OK; -} - -static status_t replace_lib_entry( MWLib *lib, const char *filename, - int idx, int verbose ) -{ - char *buff; - MWLibFile info; - char *dup_name; - - status_t retval = B_OK; - - ASSERT( lib != NULL ); - ASSERT( filename != NULL ); - ASSERT( idx <= lib->header.num_objects ); - - /* Load the file's data and info into the MWLib structure. - ** - ** We'll do it safely so we don't end up writing a bogus library in - ** the event of failure. - */ - retval = load_lib_file( filename, &buff, &info ); - if( retval != B_OK ) { - fprintf( stderr, "ar: error adding %s, %s\n", filename, - strerror( errno ) ); - - return retval; - } - - /* Attempt to allocate memory for a duplicate of the file name. - */ - dup_name = strdup( filename ); - if( dup_name == NULL ) { - fprintf( stderr, "ar: unable to allocate memory for filename\n", - filename ); - - free( buff ); - - return B_NO_MEMORY; - } - - /* All is well, so let's update the MWLib object appropriately. - */ - lib->files[idx].m_time = info.m_time; - lib->files[idx].off_filename = 0; - lib->files[idx].off_fullpath = 0; - lib->files[idx].off_object = 0; - lib->files[idx].object_size = info.object_size; - - lib->data[idx] = buff; - - free( lib->names[idx] ); - lib->names[idx] = dup_name; - - /* Give a little feedback. - */ - if( verbose ) { - printf( "r - %s\n", filename ); - } - - return B_OK; -} - -/* ---------------------------------------------------------------------- -** Print the table for an archive. -*/ -static status_t table_lib_entry( MWLib *lib, int idx, int verbose ); - -status_t do_table( const char *archive_name, char **files, int verbose ) -{ - status_t retval = B_OK; - MWLib lib; - int idx = 0; - - ASSERT( archive_name != NULL ); - - retval = load_MW_lib( &lib, archive_name ); - if( retval != B_OK ) { - switch( retval ) { - case B_FILE_NOT_FOUND: - fprintf( stderr, "ar: %s, file not found\n", archive_name ); - return retval; - break; - - default: - return retval; - break; - } - } - - if( files == NULL ) { - /* Then we print the table for the entire archive. - */ - for( idx = 0; idx < lib.header.num_objects; idx++ ) { - retval = table_lib_entry( &lib, idx, verbose ); - } - } else { - /* Then we print the table for the specified files. - */ - int which = 0; - - for( idx = 0; files[idx] != NULL; idx++ ) { - if( do_match( &lib, files[idx], &which ) ) { - retval = table_lib_entry( &lib, which, verbose ); - } - which = 0; - } - } - - return retval; -} - -static status_t table_lib_entry( MWLib *lib, int idx, int verbose ) -{ - struct tm *t; - char month_buff[4]; - - ASSERT( lib != NULL ); - - if( verbose ) { - t = localtime( &(lib->files[idx].m_time) ); - if( t == NULL ) { - fprintf( stderr, "localtime() failed, %s\n", - strerror( errno ) ); - return B_OK; - } - - if( strftime( month_buff, sizeof( month_buff ), - "%b", t ) == 0 ) { - /* TODO: error message */ - fprintf( stderr, "strftime() failed, %s\n", - strerror( errno ) ); - return B_OK; - } - - /* I wish POSIX allowed for a nicer format; even using tabs - * between some entries would be better. - */ - printf( "%s %u/%u %u %s %d %d:%d %d %s\n", - "-rw-r--r--", /* simulated mode */ - getuid(), getgid(), /* simulated uid & gid */ - lib->files[idx].object_size, - month_buff, /* abbreviated month */ - t->tm_mon, /* day of month */ - t->tm_hour, /* hour */ - t->tm_min, /* minute */ - t->tm_year, /* year */ - lib->names[idx] ); - } else { - printf( "%s\n", lib->names[idx] ); - } - - return B_OK; -} - -/* ---------------------------------------------------------------------- -** Extract one or more files from the archive. -*/ -static status_t extract_lib_entry( MWLib *lib, int idx, int verbose ); - -status_t do_extract( const char *archive_name, char **files, int verbose ) -{ - status_t retval = B_OK; - MWLib lib; - int idx = 0; - - ASSERT( archive_name != NULL ); - - retval = load_MW_lib( &lib, archive_name ); - if( retval != B_OK ) { - switch( retval ) { - case B_FILE_NOT_FOUND: - fprintf( stderr, "ar: %s, file not found\n", archive_name ); - return retval; - break; - - default: - return retval; - break; - } - } - - if( files == NULL ) { - /* Then we extract all the files. - */ - for( idx = 0; idx < lib.header.num_objects; idx++ ) { - retval = extract_lib_entry( &lib, idx, verbose ); - } - } else { - /* Then we extract the specified files. - */ - int which = 0; - - for( idx = 0; files[idx] != NULL; idx++ ) { - if( do_match( &lib, files[idx], &which ) ) { - retval = extract_lib_entry( &lib, which, verbose ); - } - which = 0; - } - } - - return retval; -} - -static status_t extract_lib_entry( MWLib *lib, int idx, int verbose ) -{ - FILE *fp; - int recs; - status_t retval = B_OK; - struct stat s; - mode_t mode_bits = 0666; /* TODO: use user's umask() instead */ - - ASSERT( lib != NULL ); - - /* Delete the file if it already exists. - */ - retval = access( lib->names[idx], F_OK ); - if( retval == 0 ) { - retval = stat( lib->names[idx], &s ); - if( retval != 0 ) { - fprintf( stderr, "ar: can't stat %s, %s\n", lib->names[idx], - strerror( errno ) ); - } else { - mode_bits = s.st_mode; - } - retval = unlink( lib->names[idx] ); - if( retval != 0 ) { - fprintf( stderr, "ar: can't unlink %s, %s\n", lib->names[idx], - strerror( retval ) ); - return B_OK; - } - } - - /* Write the file. - */ - if( verbose ) { - printf( "x - %s\n", lib->names[idx] ); - } - - fp = fopen( lib->names[idx], "w" ); - if( fp == NULL ) { - fprintf( stderr, "ar: can't open %s for write, %s\n", lib->names[idx], - strerror( errno ) ); - return B_OK; - } - - recs = fwrite( lib->data[idx], lib->files[idx].object_size, 1, fp ); - if( recs != 1 ) { - fprintf( stderr, "error writing %s, %s\n", lib->names[idx], - strerror( errno ) ); - } - - retval = fclose( fp ); - - /* Set the newly extracted file's modification time to the time - ** stored in the archive. - */ - retval = stat( lib->names[idx], &s ); - if( retval != 0 ) { - fprintf( stderr, "ar: can't stat %s, %s\n", lib->names[idx], - strerror( errno ) ); - } else { - struct utimbuf new_times; - - new_times.actime = s.st_atime; - new_times.modtime = lib->files[idx].m_time; - - retval = utime( lib->names[idx], &new_times ); - if( retval != 0 ) { - fprintf( stderr, "ar: can't set modification time for %s, %s\n", - lib->names[idx], strerror( retval ) ); - } - } - - /* Set the newly extracted file's mode. - */ - retval = chmod( lib->names[idx], mode_bits ); - if( retval != 0 ) { - fprintf( stderr, "ar: unable to change file mode for %s, %s\n", - lib->names[idx], strerror( errno ) ); - } - - /* Set the newly extracted file's type. - */ - setfiletype( lib->names[idx], "application/x-mw-library" ); - - return B_OK; -} diff --git a/BeOS/ar-1.1/commands.h b/BeOS/ar-1.1/commands.h deleted file mode 100644 index e5c28c25d0c7..000000000000 --- a/BeOS/ar-1.1/commands.h +++ /dev/null @@ -1,28 +0,0 @@ -/* -** commands.h - POSIX 1003.2 "ar" command -** -** $Id$ -** -** This isn't a pure POSIX 1003.2 ar; it only manipulates Metrowerks -** Library files, not general-purpose POSIX 1003.2 format archives. -** -** Dec. 14, 1997 Chris Herborth (chrish@kagi.com) -** -** This code is donated to the PUBLIC DOMAIN. You can use, abuse, modify, -** redistribute, steal, or otherwise manipulate this code. No restrictions -** at all. If you laugh at this code, you can't use it. -** -** This "ar" was implemented using IEEE Std 1003.2-1992 as the basis for -** the interface, and Metrowerk's published docs detailing their library -** format. Look inside for clues about how reality differs from MW's -** documentation on BeOS... -*/ - -#include - -status_t do_delete( const char *archive_name, char **files, int verbose ); -status_t do_print( const char *archive_name, char **files, int verbose ); -status_t do_replace( const char *archive_name, char **files, int verbose, - int create, int update ); -status_t do_table( const char *archive_name, char **files, int verbose ); -status_t do_extract( const char *archive_name, char **files, int verobse ); diff --git a/BeOS/ar-1.1/copy_attrs.c b/BeOS/ar-1.1/copy_attrs.c deleted file mode 100644 index c9f978de59cd..000000000000 --- a/BeOS/ar-1.1/copy_attrs.c +++ /dev/null @@ -1,128 +0,0 @@ -/* -** copy_attrs.h - copy BeFS attributes from one file to another -** -** Jan. 11, 1998 Chris Herborth (chrish@qnx.com) -** -** This code is donated to the PUBLIC DOMAIN. You can use, abuse, modify, -** redistribute, steal, or otherwise manipulate this code. No restrictions -** at all. If you laugh at this code, you can't use it. -*/ - -#include -#ifndef NO_DEBUG -#include -#define ASSERT(cond) assert(cond) -#else -#define ASSERT(cond) ((void)0) -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "copy_attrs.h" - -static const char *rcs_version_id = "$Id$"; - -/* ---------------------------------------------------------------------- -** Copy file attributes from src_file to dst_file. -*/ - -status_t copy_attrs( const char *dst_file, const char *src_file ) -{ - int dst_fd, src_fd; - status_t retval = B_OK; - DIR *fa_dir = NULL; - struct dirent *fa_ent = NULL; - char *buff = NULL; - struct attr_info fa_info; - off_t read_bytes, wrote_bytes; - - ASSERT( dst_file != NULL ); - ASSERT( src_file != NULL ); - - /* Attempt to open the files. - */ - src_fd = open( src_file, O_RDONLY ); - if( src_fd < 0 ) { - return B_FILE_NOT_FOUND; - } - - dst_fd = open( dst_file, O_WRONLY ); - if( dst_fd < 0 ) { - close( src_fd ); - return B_FILE_NOT_FOUND; - } - - /* Read the attributes, and write them to the destination file. - */ - fa_dir = fs_fopen_attr_dir( src_fd ); - if( fa_dir == NULL ) { - retval = B_IO_ERROR; - goto close_return; - } - - fa_ent = fs_read_attr_dir( fa_dir ); - while( fa_ent != NULL ) { - retval = fs_stat_attr( src_fd, fa_ent->d_name, &fa_info ); - if( retval != B_OK ) { - /* TODO: Print warning message? - */ - goto read_next_attr; - } - - if( fa_info.size > (off_t)UINT_MAX ) { - /* TODO: That's too big. Print a warning message? You could - ** copy it in chunks... - */ - goto read_next_attr; - } - - if( fa_info.size > (off_t)0 ) { - buff = malloc( (size_t)fa_info.size ); - if( buff == NULL ) { - /* TODO: Can't allocate memory for this attribute. Warning? - */ - goto read_next_attr; - } - - read_bytes = fs_read_attr( src_fd, fa_ent->d_name, fa_info.type, - 0, buff, fa_info.size ); - if( read_bytes != fa_info.size ) { - /* TODO: Couldn't read entire attribute. Warning? - */ - goto free_attr_buff; - } - - wrote_bytes = fs_write_attr( dst_fd, fa_ent->d_name, fa_info.type, - 0, buff, fa_info.size ); - if( wrote_bytes != fa_info.size ) { - /* TODO: Couldn't write entire attribute. Warning? - */ - ; - } - - free_attr_buff: - free( buff ); - - retval = B_OK; - } - - /* Read the next entry. - */ - read_next_attr: - fa_ent = fs_read_attr_dir( fa_dir ); - } - -close_return: - close( dst_fd ); - close( src_fd ); - - return retval; -} - diff --git a/BeOS/ar-1.1/copy_attrs.h b/BeOS/ar-1.1/copy_attrs.h deleted file mode 100644 index a76163603bae..000000000000 --- a/BeOS/ar-1.1/copy_attrs.h +++ /dev/null @@ -1,24 +0,0 @@ -/* -** copy_attrs.h - copy BeFS attributes from one file to another -** -** $Id$ -** -** Jan. 11, 1998 Chris Herborth (chrish@qnx.com) -** -** This code is donated to the PUBLIC DOMAIN. You can use, abuse, modify, -** redistribute, steal, or otherwise manipulate this code. No restrictions -** at all. If you laugh at this code, you can't use it. -*/ - -/* ---------------------------------------------------------------------- -** Function prototypes -** -** copy_attrs() - copy BeFS attributes from one file to another -** -** Returns: -** B_OK - all is well -** B_FILE_NOT_FOUND - can't open one of the named files -** B_IO_ERROR - can't read/write some of the file attributes -** B_NO_MEMORY - unable to allocate a buffer for the attribute data -*/ -status_t copy_attrs( const char *dest_file, const char *src_file ); diff --git a/BeOS/ar-1.1/docs/ar.html b/BeOS/ar-1.1/docs/ar.html deleted file mode 100644 index 50f002e399a4..000000000000 --- a/BeOS/ar-1.1/docs/ar.html +++ /dev/null @@ -1,234 +0,0 @@ - - - -ar - create and maintain library archives - - - -

ar

-

create and maintain library archives

- -

Synopsis

- -
-ar [-][dprtx][cuv] archive [file ...]
-
- -

Options

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - The - is optional for introducing ar command-line - arguments; this is a POSIX requirement, and I've never seen anyone - use it.
c - Don't print a diagnostic message to stderr when - archive is created.
d - Delete file(s) from archive.
p - Write the contents of the named file(s) to stdout. - If no file(s) are specified, all of the files in - archive are written in the order of the archive.
r - Replace or add file(s) to the archive. This will - create archive if it doesn't already exist.
t - Write the table of contents of archive to stdout. - If not file(s) are specified, list all of the files, - otherwise only list the specified files.
u - Update older files. When used with the r option, files - within the archive are only replaced if file has a - modification date at least as new as the file already in - the archive.
vGive verbose output.
x - Extract file(s) from the archive. If no - file(s) are specified, all of the files in archive - are extracted.
archive - The pathname of an archive file.
file - One more more pathnames of object files; only the file name is - used when comparing against the names of files in the - archive.
- -

Description

- -

The ar utility creates and maintains groups of files -combined into a library. Once a library has been created, you can -add new files, and extract, delete, or replace existing files.

- -

Exit status

- -

ar exits with one of the following values:

- - - - - - -
0Successful completion.
> 0An error occurred.
- -

Bugs

- -

No known bugs, but please read the comments in the code if -you want to use it in another application.

- -

Comments

- -

This is a POSIX 1003.2-1992 based ar command; it's not -100% POSIX 1003.2 because POSIX specifies a file format for -ar archives. The BeOS ar produces library files -compatible (at least in theory :-)) with Metrowerks -CodeWarrior for PowerPC.

- -

This ar and its source code were written as a service to -the Be developer community, to make it easier for us to port UNIX -applications and libraries. The code was written from scratch, after -reverse-engineering the Metrowerks library and object file format -(mostly because the library/object file format documentation was -incorrect).

- -

If you find this useful, please -let me know, and tell me what -you're working on. Be sure to include a URL for your homepage or your -product homepages for my -Be Community -pages.

- -

If you find any bugs, please try to fix them, and send me a context -diff (use diff -c original_file fixed_file) so I can include -your fixes in the next update. I have tested this, but these -things have a way of slipping though.

- -

If you'd like to know what other things I'm working on, take a look -at my Be -Software pages, and my -Be Happy! pages.

- -

License

- -

This program binary and its source code have been donated to the -BeOS Developer Community by Arcane Dragon Software free of charge. -You can do whatever you want with it.

- -

If you really want to show your appreciation, you could -always send me a gift of some sort; cool software you wrote, nice -pictures for my desktop, ZIP drive disks, RAM, hard drives, post -cards, a pointer to a really cool/useful/interesting web site, -an MPEG audio file of an interesting band (make sure you can give me -enough information to track down their CDs if I like it!), etc. -Send me some email and I'll let you -know where to send it.

- -

But you don't have to do anything. Just write good BeOS software. -But you're already doing that, right?

- -

Disclaimer

- -

You use this at your own risk. I've tried to ensure that the code -is correct, but software usually has bugs. If ar destroys -your valuable data, formats your hard drive, kicks your cat, and lets -the air out of your tires, I'm not responsible for it. The code is -here, so you should feel fairly safe that there's nothing evil going -on.

- -

And, as I learned once again in December 1997, you really should -keep backups of everything. I only lost a day's work, but it was -still annoying, and it could've been much, much worse.

- -

A word about the code

- -

This code isn't meant to be the ultimate in efficiency or speed, -it's intended to be fairly easy to understand and maintain -(hopefully). I was also quite keen on having something that was -correct, without jumping through a lot of unnecessary hoops.

- -

If you think this code sucks, don't use it. You're already applying -this to your choice of operating system! :-)

- -

Versions

- -
- -
1.1 (April 18, 1998)
-
Changes include: -
    -
  • Extract option (x) will preserve a file's mode bits - when overwriting an existing file (this may go away if it's - not POSIX behaviour).
  • - -
  • Extracted files will now have the proper file type.
  • - -
  • Removed attempt to use umask() to set newly created - archive's mode bits; apparently, I'm not sure how it - works and my POSIX manual isn't helping.
  • - -
  • Should be 100% endian-neutral now; using this on BeOS for - x86 is only useful if you're manipulating PowerPC - objects though. The ar in - GeekGadgets - should work fine for x86 objects/libraries.
  • - -
  • Updated the README.txt file; now it's got useful - information about building/using the POSIX ar.
  • -
- -
1.0 (January 13, 1998)
-
Initial release.
- -
- -
-

Chris Herborth (chrish@qnx.com)

- -Last modified: $Date$ - - diff --git a/BeOS/ar-1.1/docs/dumpar.py b/BeOS/ar-1.1/docs/dumpar.py deleted file mode 100644 index 93e2283a2305..000000000000 --- a/BeOS/ar-1.1/docs/dumpar.py +++ /dev/null @@ -1,271 +0,0 @@ -#! /bin/env python -""" Dump data about a Metrowerks archive file. - -$Id$ - -Based on reverse-engineering the library file format. - -Copyright (C) 1997 Chris Herborth (chrish@qnx.com) -""" - -# ---------------------------------------------------------------------- -# Standard modules -import sys -import getopt -import string -import time - -# ---------------------------------------------------------------------- -def usage(): - """ Display a usage message and exit. - """ - print "dumpar [-v] library1 [library2 ... libraryn]" - print - print "Attempt to display some useful information about the contents" - print "of the given Metrowerks library file(s)." - print - print "-v Be verbose (displays offsets along with the data)" - raise SystemExit - -# ---------------------------------------------------------------------- -def mk_long( str ): - """ convert a 4-byte string into a number - - Assumes big-endian! - """ - if len( str ) < 4: - raise ValueError, "str must be 4 bytes long" - - num = ord( str[3] ) - num = num + ord( str[2] ) * 0x100 - num = num + ord( str[1] ) * 0x10000 - num = num + ord( str[0] ) * 0x1000000 - - return num - -# ---------------------------------------------------------------------- -def str2hex( str ): - """ convert a string into a string of hex numbers - """ - ret = [] - for c in str: - h = hex( ord( c ) ) - ret.append( string.zfill( "%s" % ( h[2:] ), 2 ) ) - - return string.join( ret ) - -# ---------------------------------------------------------------------- -def print_offset( offset ): - """ print the offset nicely - """ - - # Turn the offset into a hex number and strip off the leading "0x". - val = "%s" % ( hex( offset ) ) - val = val[2:] - - out = "0x" + string.zfill( val, 8 ) - - print out, - -# ---------------------------------------------------------------------- -def get_string( data ): - """ dig a C string out of a data stream - - returns the string - """ - len = 0 - while data[len] != '\0': - len = len + 1 - - return data[:len] - -# ---------------------------------------------------------------------- -def dump_lib( file, verbose ): - """ dump information about a Metrowerks library file - """ - offset = 0 - - print "Dumping library:", file - - # Attempt to read the data. - try: - data = open( file ).read() - except IOError, retval: - print "*** Unable to open file %s: %s" % ( file, retval[1] ) - return - - # Check the magic number. - if verbose: - print_offset( offset ) - print "Magic:", - magic = data[offset:offset + 8] - print "'%s'" % ( magic ) - if magic != "MWOBPPC ": - print "*** Invalid magic number!" - return - - offset = offset + 8 - - # File flags - if verbose: - print_offset( offset ) - print "file flags:", - print mk_long( data[offset:offset + 4] ) - offset = offset + 4 - - if verbose: - print_offset( offset ) - print "file version:", - print mk_long( data[offset:offset + 4] ) - offset = offset + 4 - - # code size - if verbose: - print_offset( offset ) - print "code size:", mk_long( data[offset:offset + 4] ) - offset = offset + 4 - - # data size - if verbose: - print_offset( offset ) - print "data size:", mk_long( data[offset:offset + 4] ) - offset = offset + 4 - - # number of objects - if verbose: - print_offset( offset ) - print "number of objects:", - num_objs = mk_long( data[offset:offset + 4] ) - print num_objs - - offset = offset + 4 - - print - - # Now loop through the objects. - obj_sizes = [ 0, ] * num_objs - obj_data_offsets = [ 0, ] * num_objs - - for obj in range( num_objs ): - # Magic? - if verbose: - print_offset( offset ) - print "modification time:", - modtime = mk_long( data[offset:offset + 4] ) - print "[%s]" % ( ( time.localtime( modtime ), ) ) - - offset = offset + 4 - - # Offsets? - if verbose: - print_offset( offset ) - print "file name offset 1:", - file_offset1 = mk_long( data[offset:offset + 4] ) - unknown = "%s" % ( hex( file_offset1 ) ) - print "%s (%s)" % ( unknown, str2hex( data[offset:offset + 4] ) ) - - offset = offset + 4 - - if verbose: - print_offset( offset ) - print "file name offset 2:", - file_offset2 = mk_long( data[offset:offset + 4] ) - unknown = "%s" % ( hex( file_offset2 ) ) - print "%s (%s)" % ( unknown, str2hex( data[offset:offset + 4] ) ) - - offset = offset + 4 - - # Extra -1 for NUL character. - print " >>>> File name should be %s characters." % \ - ( file_offset2 - file_offset1 - 1) - - if verbose: - print_offset( offset ) - print "object data offset:", - file_data_offset = mk_long( data[offset:offset + 4] ) - unknown = "%s" % ( hex( file_data_offset ) ) - print "%s (%s)" % ( unknown, str2hex( data[offset:offset + 4] ) ) - - obj_data_offsets[obj] = file_data_offset - - offset = offset + 4 - - # object size - if verbose: - print_offset( offset ) - print "object size:", - obj_sizes[obj] = mk_long( data[offset:offset + 4] ) - print "%s bytes" % ( obj_sizes[obj] ) - - offset = offset + 4 - - print - - # Now loop through the object names. - for obj in range( num_objs ): - # First name - if verbose: - print_offset( offset ) - print "object", - print obj, - print "name 1:", - name1 = get_string( data[offset:] ) - print "[%s] %s chars" % ( name1, len( name1 ) ) - - offset = offset + len( name1 ) + 1 - - # Second name - if verbose: - print_offset( offset ) - print "object", - print obj, - print "name 2:", - name2 = get_string( data[offset:] ) - print "[%s] %s chars" % ( name2, len( name1 ) ) - - offset = offset + len( name2 ) + 1 - - # See if we've got a magic cookie in the object data - if verbose: - print_offset( obj_data_offsets[obj] ) - - cookie = data[obj_data_offsets[obj]:obj_data_offsets[obj] + 8] - print "object", - print obj, - print "cookie: '%s'" % ( cookie ) - - print - - # Now loop through the data and check for magic numbers there. - return - -# ---------------------------------------------------------------------- -def main(): - """ mainline - """ - - # Set up some defaults - be_verbose = 0 - - # First, check the command-line arguments - try: - opt, args = getopt.getopt( sys.argv[1:], "vh?" ) - except getopt.error: - print "*** Error parsing command-line options!" - usage() - - for o in opt: - if o[0] == "-h" or o[0] == "-?": - usage() - elif o[0] == "-v": - be_verbose = 1 - else: - print "*** Unknown command-line option!" - usage() - - # Now we can attempt to dump info about the arguments. - for lib in args: - dump_lib( lib, be_verbose ) - -if __name__ == "__main__": - main() diff --git a/BeOS/ar-1.1/docs/dumpo.py b/BeOS/ar-1.1/docs/dumpo.py deleted file mode 100644 index 91bd8db699fb..000000000000 --- a/BeOS/ar-1.1/docs/dumpo.py +++ /dev/null @@ -1,126 +0,0 @@ -#! /bin/env python -""" Dump data about a Metrowerks object file. - -Based on reverse-engineering the library file format, since the docs are -wrong. - -Copyright (C) 1997 Chris Herborth (chrish@qnx.com) -""" - -# ---------------------------------------------------------------------- -# Standard modules -import sys, getopt, string, time - -# ---------------------------------------------------------------------- -# Extra goodies -from dumpar import mk_long, str2hex, print_offset, get_string - -# ---------------------------------------------------------------------- -def mk_short( str ): - """ convert a 2-byte string into a number - - Assumes big-endian! - """ - if len( str ) < 2: - raise ValueError, "str must be 2 bytes long" - - num = ord( str[1] ) - num = num + ord( str[0] ) * 0x100 - - return num - -# ---------------------------------------------------------------------- -def usage(): - """ Display a usage message and exit. - """ - print "dumpo [-v] object1 [object2 ... objectn]" - print - print "Attempt to display some useful information about the contents" - print "of the given Metrowerks object file(s)." - print - print "-v Be verbose (displays offsets along with the data)" - raise SystemExit - -# ---------------------------------------------------------------------- -def dump_o( file, verbose ): - """ dump information about a Metrowerks object file - - Note that there is more info there, 6 more quads before the file name. - """ - offset = 0 - - print "Dumping object:", file - - # Attempt to read the data. - try: - data = open( file ).read() - except IOError, retval: - print "*** Unable to open file %s: %s" % ( file, retval[1] ) - return - - # Check the magic number. - if verbose: - print_offset( offset ) - print "Magic:", - magic = data[offset:offset + 8] - print "'%s'" % ( magic ) - if magic != "MWOBPPC ": - print "*** Invalid magic number!" - return - - offset = offset + 8 - - # version - if verbose: - print_offset( offset ) - print "version:", mk_long( data[offset:offset + 4] ) - offset = offset + 4 - - # flags - if verbose: - print_offset( offset ) - print "flags:", str2hex( data[offset:offset + 4] ) - offset = offset + 4 - - # code size - if verbose: - print_offset( offset ) - print "code size:", mk_long( data[offset:offset + 4] ) - offset = offset + 4 - - # data size - if verbose: - print_offset( offset ) - print "data size:", mk_long( data[offset:offset + 4] ) - offset = offset + 4 - -# ---------------------------------------------------------------------- -def main(): - """ mainline - """ - - # Set up some defaults - be_verbose = 0 - - # First, check the command-line arguments - try: - opt, args = getopt.getopt( sys.argv[1:], "vh?" ) - except getopt.error: - print "*** Error parsing command-line options!" - usage() - - for o in opt: - if o[0] == "-h" or o[0] == "-?": - usage() - elif o[0] == "-v": - be_verbose = 1 - else: - print "*** Unknown command-line option!" - usage() - - # Now we can attempt to dump info about the arguments. - for obj in args: - dump_o( obj, be_verbose ) - -if __name__ == "__main__": - main() diff --git a/BeOS/ar-1.1/docs/notes b/BeOS/ar-1.1/docs/notes deleted file mode 100644 index 4a90a16b3787..000000000000 --- a/BeOS/ar-1.1/docs/notes +++ /dev/null @@ -1,34 +0,0 @@ -MW library layout: - -header - magic word, magic processor flag ('MWOBPPC ') - 2x 4 bytes - magic flags, version (file format version?) - 2x 4 bytes - code size - 4 bytes - data size - 4 bytes - # of objects - 4 bytes - - header for file 1 - 20 bytes - - modification time - 4 bytes - - offset to filename - 4 bytes - - offset to full path - 4 bytes (NOTE: NOT a full path in reality!) - - offset to object data - 4 bytes - - size of object data - 4 bytes - - ... - - header for file n - 20 bytes - - file 1 name + NUL - variable - file 1 name + NUL - variable - file 2 name + NUL - variable - file 2 name + NUL - variable - ... - file n name + NUL - variable - file n name + NUL - variable - - padding to multiple of 4 bytes - 0 - 3 bytes - -file 1 data - variable (padded to 4-byte boundary) -file 2 data - variable (padded to 4-byte boundary) -... -file n data - variable (padded to 4-byte boundary) diff --git a/BeOS/ar-1.1/main.c b/BeOS/ar-1.1/main.c deleted file mode 100644 index 225ee628dd25..000000000000 --- a/BeOS/ar-1.1/main.c +++ /dev/null @@ -1,312 +0,0 @@ -/* -** main.c - POSIX 1003.2 "ar" command -** -** This isn't a pure POSIX 1003.2 ar; it only manipulates Metrowerks -** Library files, not general-purpose POSIX 1003.2 format archives. -** -** Dec. 14, 1997 Chris Herborth (chrish@kagi.com) -** -** This code is donated to the PUBLIC DOMAIN. You can use, abuse, modify, -** redistribute, steal, or otherwise manipulate this code. No restrictions -** at all. If you laugh at this code, you can't use it. -** -** This "ar" was implemented using IEEE Std 1003.2-1992 as the basis for -** the interface, and Metrowerk's published docs detailing their library -** format. Look inside for clues about how reality differs from MW's -** documentation on BeOS... -*/ - -#include -#include -#include -#include - -#include "commands.h" - -static const char *rcs_version_id = "$Id$"; -static const char *ar_version_id = "1.0 " __DATE__; - -/* ---------------------------------------------------------------------- */ -typedef enum { - delete_cmd, - print_cmd, - replace_cmd, - table_cmd, - extract_cmd, - no_cmd = -1 } command; - -/* ---------------------------------------------------------------------- -** Prototypes -*/ -void usage( void ); -void version( void ); -void check_command( command *cmd, int arg ); - -/* ---------------------------------------------------------------------- -** Print a usage message and exit. -*/ -void usage( void ) -{ - printf( "ar [dprtx][cuv] archive [file ...]\n" ); - - exit( EXIT_FAILURE ); -} - -/* ---------------------------------------------------------------------- -** Print a version message and exit. -*/ -void version( void ) -{ - printf( "ar (POSIX 1003.2-1992), version %s\n", ar_version_id ); - printf( "by Chris Herborth (chrish@qnx.com)\n" ); - printf( "This code has been donated to the BeOS developer community.\n" ); - - return; -} - -/* ---------------------------------------------------------------------- -** Set *cmd to the appropriate command enum if it isn't already set. -*/ -void check_command( command *cmd, int arg ) -{ - if( *cmd == no_cmd ) { - switch( arg ) { - case 'd': - *cmd = delete_cmd; - break; - case 'p': - *cmd = print_cmd; - break; - case 'r': - *cmd = replace_cmd; - break; - case 't': - *cmd = table_cmd; - break; - case 'x': - *cmd = extract_cmd; - break; - } - } else { - printf( "ar: you can only specify one command at a time\n" ); - usage(); - } -} - -/* ---------------------------------------------------------------------- -** Mainline -*/ -int main( int argc, char **argv ) -{ - command cmd = no_cmd; - int verbose_flag = 0; - int create_flag = 0; /* these two only apply to replace_cmd */ - int update_flag = 0; - int c = 0; - - char *archive_name; - char **files_list; - int num_files; - - int idx; - status_t retval; - - /* The argument parsing is a little hairier than usual; the idea is - ** to support the POSIX 1003.2 style of arguments, and the much more - ** common traditional argument style. - */ - if( argc < 3 ) { - printf( "ar: invalid number of arguments\n" ); - usage(); - } - - /* Do we have traditional or POSIX-style args? */ - if( argv[1][0] == '-' ) { - while( ( c = getopt( argc, argv, "dprtxcuvV" ) ) != EOF ) { - switch( c ) { - case 'd': /* fall-through */ - case 'p': /* fall-through */ - case 'r': /* fall-through */ - case 't': /* fall-through */ - case 'x': /* fall-through */ - check_command( &cmd, c ); - break; - - case 'v': - verbose_flag = 1; - break; - - case 'c': - if( cmd != no_cmd && cmd != replace_cmd ) { - printf( "ar: invalid option, -c\n" ); - usage(); - } else { - create_flag = 1; - } - break; - - case 'u': - if( cmd != no_cmd && cmd != replace_cmd ) { - printf( "ar: invalid option, -u\n" ); - usage(); - } else { - update_flag = 1; - } - break; - - case 'V': - version(); - break; - - default: - printf( "ar: invalid option, -%c\n", c ); - usage(); - break; - } - - idx = optind; - } - } else { - /* In the traditional way, arguments ar: - ** - ** argv[1] = [dprtx][cuv] - ** argv[2] = archive - ** argv[...] = file ... - **/ - char *ptr; - - idx = 1; - - ptr = argv[idx++]; - - while( *ptr != '\0' ) { - switch( *ptr ) { - case 'd': /* fall-through */ - case 'p': /* fall-through */ - case 'r': /* fall-through */ - case 't': /* fall-through */ - case 'x': /* fall-through */ - check_command( &cmd, *ptr ); - break; - - case 'v': - verbose_flag = 1; - break; - - case 'c': - if( cmd != no_cmd && cmd != replace_cmd ) { - printf( "ar: invalid option, -c\n" ); - usage(); - } else { - create_flag = 1; - } - break; - - case 'u': - if( cmd != no_cmd && cmd != replace_cmd ) { - printf( "ar: invalid option, -u\n" ); - usage(); - } else { - update_flag = 1; - } - break; - - case 'V': - version(); - break; - - default: - printf( "ar: invalid option, -%c\n", c ); - usage(); - break; - } - - ptr++; - } - } - - /* Next arg is the archive. */ - archive_name = argv[idx++]; - - /* Next are the files. */ - num_files = argc - idx; - - if( num_files == 0 ) { - files_list = NULL; - } else { - int ctr = 0; - - files_list = (char **)malloc( ( num_files + 1 ) * sizeof( char * ) ); - - while( idx < argc ) { - files_list[ctr++] = argv[idx++]; - } - - files_list[idx] = NULL; - } - - /* Now we can attempt to manipulate the archive. */ - switch( cmd ) { - case delete_cmd: - retval = do_delete( archive_name, files_list, verbose_flag ); - break; - - case print_cmd: - retval = do_print( archive_name, files_list, verbose_flag ); - break; - - case replace_cmd: - retval = do_replace( archive_name, files_list, verbose_flag, - create_flag, update_flag ); - break; - - case table_cmd: - retval = do_table( archive_name, files_list, verbose_flag ); - break; - - case extract_cmd: - retval = do_extract( archive_name, files_list, verbose_flag ); - break; - - default: - printf( "ar: you must specify a command\n" ); - usage(); - break; - } - - /* Check the return value. - */ - switch( retval ) { - case B_OK: - break; - case B_FILE_NOT_FOUND: - printf( "can't open the file %s\n", archive_name ); - return EXIT_FAILURE; - break; - case B_IO_ERROR: - printf( "can't read from %s\n", archive_name ); - return EXIT_FAILURE; - break; - case B_BAD_VALUE: - printf( "invalid magic word\n" ); - return EXIT_FAILURE; - break; - case B_MISMATCHED_VALUES: - printf( "invalid processor value, or magicflags, or version\n" ); - return EXIT_FAILURE; - break; - case B_NO_MEMORY: - printf( "unable to allocate memory\n" ); - return EXIT_FAILURE; - break; - case B_ERROR: - printf( "error during processing\n" ); - return EXIT_FAILURE; - default: - printf( "unknown error: %ld\n", retval ); - return EXIT_FAILURE; - break; - } - - return EXIT_SUCCESS; -} diff --git a/BeOS/ar-1.1/mwlib.c b/BeOS/ar-1.1/mwlib.c deleted file mode 100644 index f3b86605fd79..000000000000 --- a/BeOS/ar-1.1/mwlib.c +++ /dev/null @@ -1,711 +0,0 @@ -/* -** mwlib.c - POSIX 1003.2 "ar" command -** -** This isn't a pure POSIX 1003.2 ar; it only manipulates Metrowerks -** Library files, not general-purpose POSIX 1003.2 format archives. -** -** Dec. 14, 1997 Chris Herborth (chrish@kagi.com) -** -** This code is donated to the PUBLIC DOMAIN. You can use, abuse, modify, -** redistribute, steal, or otherwise manipulate this code. No restrictions -** at all. If you laugh at this code, you can't use it. -** -** This "ar" was implemented using IEEE Std 1003.2-1992 as the basis for -** the interface, and Metrowerk's published docs detailing their library -** format. Look inside for clues about how reality differs from MW's -** documentation on BeOS... -*/ - -#include -#include -#ifndef NO_DEBUG -#include -#define ASSERT(cond) assert(cond) -#else -#define ASSERT(cond) ((void)0) -#endif - -#include -#include -#include -#include -#include -#include -#include -#include /* is open() really here?!? sheesh... */ -#include -#include - -#include "mwlib.h" -#include "copy_attrs.h" - -static const char *rcs_version_id = "$Id$"; - -/* ---------------------------------------------------------------------- -** Local prototypes -*/ -static status_t load_MWLibFile( FILE *file, MWLibFile *libfile ); -static size_t fwrite_big32( uint32 x, FILE *fp ); -static size_t fwrite_big32_seek( uint32 x, long offset, FILE *fp ); -static status_t add_object_sizes( MWObject *obj, uint32 *code, uint32 *data ); - -/* ---------------------------------------------------------------------- -** Load a Metrowerks library file into the given MWLib object. -** -** Returns: -** B_OK - all is well -** B_FILE_NOT_FOUND - can't open the given file -** B_IO_ERROR - can't read from the given file -** B_BAD_VALUE - invalid magic word in the file -** B_MISMATCHED_VALUES - invalid processor value (ie, not a PowerPC lib), -** or the magicflags member is not 0, or the file -** version number isn't 1. -** B_NO_MEMORY - unable to allocate memory while loading the lib -*/ -status_t load_MW_lib( MWLib *lib, const char *filename ) -{ - FILE *fp = NULL; - size_t recs = 0; - status_t retval = B_OK; - uint32 tmp32 = 0; - uint32 idx = 0; - char obj_name[PATH_MAX]; - - ASSERT( lib != NULL ); - ASSERT( filename != NULL ); - - fp = fopen( filename, "r" ); - if( !fp ) { - return B_FILE_NOT_FOUND; - } - - /* Read and check the magic number. - */ - recs = fread( &tmp32, sizeof( uint32 ), 1, fp ); - lib->header.magicword = B_BENDIAN_TO_HOST_INT32( tmp32 ); - if( recs != 1 ) { - retval = B_IO_ERROR; - goto close_return; - } else if( lib->header.magicword != MWLIB_MAGIC_WORD ) { - retval = B_BAD_VALUE; - goto close_return; - } - - /* Read and check the processor. - */ - recs = fread( &tmp32, sizeof( uint32 ), 1, fp ); - lib->header.magicproc = B_BENDIAN_TO_HOST_INT32( tmp32 ); - if( recs != 1 ) { - retval = B_IO_ERROR; - goto close_return; - } else if( lib->header.magicproc != MWLIB_MAGIC_PROC ) { - retval = B_MISMATCHED_VALUES; - goto close_return; - } - - /* Read and check the flags. - */ - recs = fread( &tmp32, sizeof( uint32 ), 1, fp ); - lib->header.magicflags = B_BENDIAN_TO_HOST_INT32( tmp32 ); - if( recs != 1 ) { - retval = B_IO_ERROR; - goto close_return; - } else if( lib->header.magicflags != 0 ) { - retval = B_MISMATCHED_VALUES; - goto close_return; - } - - /* Read and check the file version. - */ - recs = fread( &tmp32, sizeof( uint32 ), 1, fp ); - lib->header.version = B_BENDIAN_TO_HOST_INT32( tmp32 ); - if( recs != 1 ) { - retval = B_IO_ERROR; - goto close_return; - } else if( lib->header.version != 1 ) { - retval = B_MISMATCHED_VALUES; - goto close_return; - } - - /* Read the code size, data size, and number of objects. - */ - recs = fread( &tmp32, sizeof( uint32 ), 1, fp ); - lib->header.code_size = B_BENDIAN_TO_HOST_INT32( tmp32 ); - if( recs != 1 ) { - retval = B_IO_ERROR; - goto close_return; - } - - recs = fread( &tmp32, sizeof( uint32 ), 1, fp ); - lib->header.data_size = B_BENDIAN_TO_HOST_INT32( tmp32 ); - if( recs != 1 ) { - retval = B_IO_ERROR; - goto close_return; - } - - recs = fread( &tmp32, sizeof( uint32 ), 1, fp ); - lib->header.num_objects = B_BENDIAN_TO_HOST_INT32( tmp32 ); - if( recs != 1 ) { - retval = B_IO_ERROR; - goto close_return; - } - - /* Load the MWLibFile objects from the lib. - */ - lib->files = (MWLibFile *)malloc( lib->header.num_objects * sizeof( MWLibFile ) ); - if( lib->files == NULL ) { - retval = B_NO_MEMORY; - goto close_return; - } - - for( idx = 0; idx < lib->header.num_objects; idx++ ) { - retval = load_MWLibFile( fp, &(lib->files[idx]) ); - if( retval != B_OK ) { - goto close_return; - } - } - - /* Load the file names and object data. - ** - ** The file name actually appears twice in the library file; according - ** to the docs, one is the file name, the other is the "full path name". - ** In all of the libraries on my system, they're the same. - */ - lib->names = (char **)malloc( lib->header.num_objects * sizeof( char * ) ); - lib->data = (char **)malloc( lib->header.num_objects * sizeof( char * ) ); - if( lib->names == NULL || lib->data == NULL ) { - retval = B_NO_MEMORY; - goto close_return; - } - - for( idx = 0; idx < lib->header.num_objects; idx ++ ) { - /* Load the name and copy it into the right spot. - */ - retval = fseek( fp, lib->files[idx].off_filename, SEEK_SET ); - if( retval ) { - retval = B_IO_ERROR; - goto close_return; - } - - if( fgets( obj_name, PATH_MAX, fp ) == NULL ) { - retval = B_IO_ERROR; - goto close_return; - } - - lib->names[idx] = strdup( obj_name ); - if( lib->names[idx] == NULL ) { - retval = B_NO_MEMORY; - goto close_return; - } - - /* Load the object data. - */ - lib->data[idx] = (char *)malloc( lib->files[idx].object_size ); - if( lib->data[idx] == NULL ) { - retval = B_NO_MEMORY; - goto close_return; - } - - retval = fseek( fp, lib->files[idx].off_object, SEEK_SET ); - if( retval ) { - retval = B_IO_ERROR; - goto close_return; - } - - recs = fread( lib->data[idx], lib->files[idx].object_size, 1, fp ); - if( recs != 1 ) { - retval = B_IO_ERROR; - goto close_return; - } - } - -close_return: - fclose( fp ); - return retval; -} - -/* ---------------------------------------------------------------------- -** Load the file header from a Metrowerks library file. -** -** Returns: -** B_OK - All is well -** B_IO_ERROR - Error reading the file -*/ -static status_t load_MWLibFile( FILE *file, MWLibFile *libfile ) -{ - size_t recs = 0; - uint32 tmp32 = 0; - - ASSERT( file != NULL ); - ASSERT( libfile != NULL ); - - /* Load the modification time. - */ - recs = fread( &tmp32, sizeof( uint32 ), 1, file ); - libfile->m_time = (time_t)B_BENDIAN_TO_HOST_INT32( tmp32 ); - if( recs != 1 ) { - return B_IO_ERROR; - } - - /* Load the various offsets. - */ - recs = fread( &tmp32, sizeof( uint32 ), 1, file ); - libfile->off_filename = B_BENDIAN_TO_HOST_INT32( tmp32 ); - if( recs != 1 ) { - return B_IO_ERROR; - } - - recs = fread( &tmp32, sizeof( uint32 ), 1, file ); - libfile->off_fullpath = B_BENDIAN_TO_HOST_INT32( tmp32 ); - if( recs != 1 ) { - return B_IO_ERROR; - } - - recs = fread( &tmp32, sizeof( uint32 ), 1, file ); - libfile->off_object = B_BENDIAN_TO_HOST_INT32( tmp32 ); - if( recs != 1 ) { - return B_IO_ERROR; - } - - /* Load the object size. - */ - recs = fread( &tmp32, sizeof( uint32 ), 1, file ); - libfile->object_size = B_BENDIAN_TO_HOST_INT32( tmp32 ); - if( recs != 1 ) { - return B_IO_ERROR; - } - - return B_OK; -} - -/* ---------------------------------------------------------------------- -** Write a Metrowerks library file. -** -** Returns: -** B_OK - all is well; doesn't necessarily mean the file was written -** properly, just that you didn't lose any data -** B_NO_MEMORY - unable to allocate offset buffers -** B_ERROR - problem with backup file (can't rename existing file) -** -** Note: -** If you use this in a long-lived program, it leaks memory; the MWLib -** contents are never free()'d. -** -** Two-pass technique: -** -** pass 1 - write file header (need CODE SIZE and DATA SIZE) -** write object headers (need offsets for FILENAME, FULL PATH, DATA) -** write filenames (store offsets for object headers) -** write padding (file size % 4 bytes) -** write file data (store offset for object header; add to code/data -** size for file header; pad data size % 4 bytes) -** -** pass 2 - fill in file header CODE SIZE and DATA SIZE -** fill in object headers FILENAME, FULL PATH, DATA -** -** You could avoid this by building up the file headers in memory, but this is -** easier (?) and I'm not that concerned with speed... -** -*/ - -typedef struct file_header_offsets { - long codesize_offset; - long datasize_offset; -} file_header_offsets; - -typedef struct obj_header_offsets { - long filename_offset; - uint32 filename_offset_value; - - long fullpath_offset; - uint32 fullpath_offset_value; - - long data_offset; - uint32 data_offset_value; -} obj_header_offsets; - -static size_t fwrite_big32( uint32 x, FILE *fp ) -{ - uint32 tmp32 = B_HOST_TO_BENDIAN_INT32( x ); - - ASSERT( fp != NULL ); - - return fwrite( &tmp32, sizeof(tmp32), 1, fp ); -} - -static size_t fwrite_big32_seek( uint32 x, long offset, FILE *fp ) -{ - uint32 tmp32 = B_HOST_TO_BENDIAN_INT32( x ); - - ASSERT( fp != NULL ); - - if( fseek( fp, offset, SEEK_SET ) ) { - return 0; - } - - return fwrite( &tmp32, sizeof(tmp32), 1, fp ); -} - -static status_t add_object_sizes( MWObject *obj, uint32 *code, uint32 *data ) -{ - ASSERT( obj != NULL ); - ASSERT( code != NULL ); - ASSERT( data != NULL ); - - if( B_BENDIAN_TO_HOST_INT32( obj->magic_word ) != 'MWOB' || - B_BENDIAN_TO_HOST_INT32( obj->arch ) != 'PPC ' ) { - return B_ERROR; - } - - *code += B_BENDIAN_TO_HOST_INT32( obj->code_size ); - *data += B_BENDIAN_TO_HOST_INT32( obj->data_size ); - - return B_OK; -} - -void setfiletype( const char *file, const char *type ) -{ - int fd; - attr_info fa; - ssize_t wrote_bytes; - - fd = open( file, O_RDWR ); - if( fd < 0 ) { - fprintf( stderr, "ar: can't open %s to write file type, %s", - file, strerror( errno ) ); - return; - } - - fa.type = B_MIME_STRING_TYPE; - fa.size = (off_t)(strlen( type ) + 1); - - wrote_bytes = fs_write_attr( fd, "BEOS:TYPE", fa.type, 0, - type, fa.size ); - if( wrote_bytes != (ssize_t)fa.size ) { - fprintf( stderr, "ar: couldn't write complete file type, %s", - strerror( errno ) ); - } - - close( fd ); -} - -status_t write_MW_lib( MWLib *lib, const char *filename ) -{ - char *padding = "\0\0\0\0"; - long pad_amount; - - file_header_offsets head_offs; - obj_header_offsets *obj_offs; - uint32 codesize = 0; - uint32 datasize = 0; - uint32 num_objects = 0; - - FILE *fp; - char *tmp_filename = NULL; - uint32 idx = 0; - size_t recs; - status_t retval; - - mode_t mode_bits = 0666; - - ASSERT( lib != NULL ); - ASSERT( filename != NULL ); - -#if 0 -/* Apparently, I don't understand umask()... */ - - /* Find the default file creation mask. The semantics of umask() suck. - */ - mode_bits = umask( (mode_t)0 ); - (void)umask( mode_bits ); -#endif - - /* Easier access to the number of objects. - */ - num_objects = lib->header.num_objects; - - /* Allocate some storage for keeping track of the things we need to - ** write out in the second pass. - */ - head_offs.codesize_offset = 0; - head_offs.datasize_offset = 0; - - obj_offs = (obj_header_offsets *)malloc( sizeof(obj_header_offsets) * - num_objects ); - if( obj_offs == NULL ) { - fprintf( stderr, "ar: can't allocate memory for writing file\n" ); - - return B_NO_MEMORY; - } - memset( obj_offs, 0, sizeof(obj_header_offsets) * num_objects ); - - /* If the file exists, move it somewhere so we can recover if there's - ** an error. - */ - retval = access( filename, F_OK ); - if( retval == 0 ) { - struct stat s; - - /* Preserve the mode bits. - */ - retval = stat( filename, &s ); - if( retval != 0 ) { - fprintf( stderr, "ar: can't stat %s, %s\n", filename, - strerror( errno ) ); - } else { - mode_bits = s.st_mode; - } - - tmp_filename = (char *)malloc( strlen( filename ) + 2 ); - if( tmp_filename == NULL ) { - fprintf( stderr, - "ar: can't allocate memory for temporary filename\n" ); - } else { - sprintf( tmp_filename, "%s~", filename ); - - retval = access( tmp_filename, F_OK ); - if( retval == 0 ) { - retval = unlink( tmp_filename ); - if( retval != 0 ) { - fprintf( stderr, "ar: can't unlink %s, %s\n", tmp_filename, - strerror( errno ) ); - - free( tmp_filename ); - tmp_filename = NULL; - } - } - - if( tmp_filename ) { - retval = rename( filename, tmp_filename ); - if( retval != 0 ) { - fprintf( stderr, "ar: can't move %s to backup, %s\n", - filename, strerror( errno ) ); - - return B_ERROR; - } - } - } - } - - /* Attempt to open the archive file. - */ - fp = fopen( filename, "w" ); - if( fp == NULL ) { - fprintf( stderr, "ar: can't open %s for write, %s\n", filename, - strerror( errno ) ); - goto error_return; - } - - /* ---------------------------------------------------------------------- - ** Write the file. Pass 1. - */ - recs = fwrite_big32( lib->header.magicword, fp ); - recs += fwrite_big32( lib->header.magicproc, fp ); - recs += fwrite_big32( lib->header.magicflags, fp ); - recs += fwrite_big32( lib->header.version, fp ); - if( recs != 4 ) { - fprintf( stderr, "ar: error writing header for %s, %s\n", filename, - strerror( errno ) ); - goto error_return; - } - - /* Keep track of the code/data size offsets. - */ - head_offs.codesize_offset = ftell( fp ); - recs = fwrite_big32( codesize, fp ); - head_offs.datasize_offset = ftell( fp ); - recs += fwrite_big32( datasize, fp ); - if( recs != 2 ) { - fprintf( stderr, "ar: error writing header for %s, %s\n", filename, - strerror( errno ) ); - goto error_return; - } - - recs = fwrite_big32( num_objects, fp ); - if( recs != 1 ) { - fprintf( stderr, "ar: error writing header for %s, %s\n", filename, - strerror( errno ) ); - goto error_return; - } - - /* Write the object headers. - */ - for( idx = 0; idx < num_objects; idx++ ) { - recs = fwrite_big32( lib->files[idx].m_time, fp ); - - /* Keep track of the offsets, and write 0 for now. - */ - obj_offs[idx].filename_offset = ftell( fp ); - recs += fwrite_big32( 0, fp ); - obj_offs[idx].fullpath_offset = ftell( fp ); - recs += fwrite_big32( 0, fp ); - obj_offs[idx].data_offset = ftell( fp ); - recs += fwrite_big32( 0, fp ); - - recs += fwrite_big32( lib->files[idx].object_size, fp ); - - if( recs != 5 ) { - fprintf( stderr, "ar: error writing object header for %s, %s\n", - filename, strerror( errno ) ); - goto error_return; - } - } - - /* Write the file names. - */ - for( idx = 0; idx < num_objects; idx++ ) { - /* Need to make sure that all the file names we write into the - ** library DO NOT HAVE PATHS IN THEM, the world might end or something. - */ - size_t name_len = 0; - char *name_ptr = strrchr( lib->names[idx], '/' ); - - if( name_ptr == NULL ) { - name_ptr = lib->names[idx]; - } else { - name_ptr++; - } - - name_len = strlen( name_ptr ) + 1; - - obj_offs[idx].filename_offset_value = ftell( fp ); - recs = fwrite( name_ptr, name_len, 1, fp ); - obj_offs[idx].fullpath_offset_value = ftell( fp ); - recs += fwrite( name_ptr, name_len, 1, fp ); - - if( recs != 2 ) { - fprintf( stderr, "ar: error writing object name for %s, %s\n", - filename, strerror( errno ) ); - goto error_return; - } - } - - /* Pad the file if necessary. - */ - pad_amount = ftell( fp ) % 4; - if( pad_amount > 0 ) { - recs = fwrite( padding, pad_amount, 1, fp ); - - if( recs != 1 ) { - fprintf( stderr, "ar: error padding file %s, %s\n", filename, - strerror( errno ) ); - goto error_return; - } - } - - /* Write the object file data. - */ - for( idx = 0; idx < num_objects; idx++ ) { - obj_offs[idx].data_offset_value = ftell( fp ); - - recs = fwrite( lib->data[idx], lib->files[idx].object_size, 1, fp ); - if( recs != 1 ) { - fprintf( stderr, "ar: writing object data for %s, %s\n", filename, - strerror( errno ) ); - goto error_return; - } - - /* Add up the code/data size. - */ - retval = add_object_sizes( (MWObject *)lib->data[idx], - &codesize, &datasize ); - if( retval != B_OK ) { - fprintf( stderr, "ar - warning: %s is not an object file!\n", - lib->names[idx] ); - goto error_return; - } - - pad_amount = ftell( fp ) % 4; - if( pad_amount > 0 ) { - recs = fwrite( padding, pad_amount, 1, fp ); - - if( recs != 1 ) { - fprintf( stderr, "ar: error padding file %s, %s\n", filename, - strerror( errno ) ); - goto error_return; - } - } - } - - /* ---------------------------------------------------------------------- - ** Write the offsets into the file. Pass 2. - */ - - /* Write the code/data sizes. - */ - recs = fwrite_big32_seek( codesize, head_offs.codesize_offset, fp ); - recs += fwrite_big32_seek( datasize, head_offs.datasize_offset, fp ); - if( recs != 2 ) { - fprintf( stderr, "ar - error writing code and data sizes, %s\n", - strerror( errno ) ); - goto error_return; - } - - /* Write the offsets for each file. - */ - for( idx = 0; idx < num_objects; idx++ ) { - recs = fwrite_big32_seek( obj_offs[idx].filename_offset_value, - obj_offs[idx].filename_offset, fp ); - recs += fwrite_big32_seek( obj_offs[idx].fullpath_offset_value, - obj_offs[idx].fullpath_offset, fp ); - recs += fwrite_big32_seek( obj_offs[idx].data_offset_value, - obj_offs[idx].data_offset, fp ); - - if( recs != 3 ) { - fprintf( stderr, "ar - error writing object offsets, %s\n", - strerror( errno ) ); - goto error_return; - } - } - - /* If all is OK, close the file and get out of here after nuking the - ** temp file (if any), preserving the original file mode, and preserving - ** the file attributes. - */ - - fclose( fp ); - - /* Preserve the original file mode bits. - */ - retval = chmod( filename, mode_bits ); - if( retval != 0 ) { - fprintf( stderr, "ar: unable to change file mode for %s, %s\n", - filename, strerror( errno ) ); - } - - /* Nuke the temp file (if any), after copying over any file attributes. - */ - if( tmp_filename != NULL ) { - retval = copy_attrs( filename, tmp_filename ); - - retval = unlink( tmp_filename ); - if( retval != 0 ) { - fprintf( stderr, "ar - error unlinking %s, %s\n", tmp_filename, - strerror( errno ) ); - } - free( tmp_filename ); - } else { - /* If there isn't a temp file, we should still give this new - ** file a file type attribute. - */ - setfiletype( filename, "application/x-mw-library" ); - } - - return B_OK; - -error_return: - /* Restore the original file if we had any problems. - */ - fclose( fp ); - - if( tmp_filename != NULL ) { - retval = unlink( filename ); - retval = rename( tmp_filename, filename ); - if( retval != 0 ) { - fprintf( stderr, "ar: can't restore %s to %s, %s\n", - tmp_filename, filename, strerror( errno ) ); - } - } - - return B_ERROR; -} diff --git a/BeOS/ar-1.1/mwlib.h b/BeOS/ar-1.1/mwlib.h deleted file mode 100644 index 67af32556c4d..000000000000 --- a/BeOS/ar-1.1/mwlib.h +++ /dev/null @@ -1,118 +0,0 @@ -/* -** mwlib.h - POSIX 1003.2 "ar" command -** -** $Id$ -** -** This isn't a pure POSIX 1003.2 ar; it only manipulates Metrowerks -** Library files, not general-purpose POSIX 1003.2 format archives. -** -** Dec. 14, 1997 Chris Herborth (chrish@qnx.com) -** -** This code is donated to the PUBLIC DOMAIN. You can use, abuse, modify, -** redistribute, steal, or otherwise manipulate this code. No restrictions -** at all. If you laugh at this code, you can't use it. -** -** This "ar" was implemented using IEEE Std 1003.2-1992 as the basis for -** the interface, and Metrowerk's published docs detailing their library -** format. Look inside for clues about how reality differs from MW's -** documentation on BeOS... -*/ - -#include -#include - -/* ---------------------------------------------------------------------- -** Constants -** -*/ -#define MWLIB_MAGIC_WORD 'MWOB' -#define MWLIB_MAGIC_PROC 'PPC ' - -/* ---------------------------------------------------------------------- -** Structures -** -** This is based on the "Metrowerks CodeWarrior Library Reference -** Specification", which isn't 100% accurate for BeOS. -*/ - -typedef struct MWLibHeader { - uint32 magicword; - uint32 magicproc; - uint32 magicflags; - uint32 version; - - uint32 code_size; - uint32 data_size; - - uint32 num_objects; -} MWLibHeader; - -typedef struct MWLibFile { - time_t m_time; - - uint32 off_filename; - uint32 off_fullpath; - uint32 off_object; - uint32 object_size; -} MWLibFile; - -typedef struct MWLib { - MWLibHeader header; - - MWLibFile *files; - - char **names; - - char **data; -} MWLib; - -/* This bears no resemblance to what's in the Metrowerks docs. -** -** Note that this is incomplete; this is all the info I needed for -** ar though. -*/ -typedef struct MWObject { - uint32 magic_word; /* 'MWOB' */ - uint32 arch; /* 'PPC '; this isn't in the docs */ - uint32 version; - uint32 flags; - - uint32 code_size; - uint32 data_size; -} MWObject; - -/* ---------------------------------------------------------------------- -** Function prototypes -** -** load_MW_lib() - load a Metrowerks library -** -** Returns: -** B_OK - all is well -** B_FILE_NOT_FOUND - can't open the given file -** B_IO_ERROR - can't read from the given file -** B_BAD_VALUE - invalid magic word in the file -** B_MISMATCHED_VALUES - invalid processor value (ie, not a PowerPC lib), -** or the magicflags member is not 0, or the file -** version number isn't 1. -** B_NO_MEMORY - unable to allocate memory while loading the lib -** -** write_MW_lib() - write a Metrowerks library -** -** Returns: -** B_OK - all is well -** -** write_MW_lib() - write a Metrowerks library file -** -** Returns: -** B_OK - all is well; doesn't necessarily mean the file was written -** properly, just that you didn't lose any data -** B_NO_MEMORY - unable to allocate offset buffers -** B_ERROR - problem with backup file (can't rename existing file) -** -** Note: -** If you use this in a long-lived program, it leaks memory; the MWLib -** contents are never free()'d. -*/ -status_t load_MW_lib( MWLib *lib, const char *filename ); -status_t write_MW_lib( MWLib *lib, const char *filename ); -void setfiletype( const char *filename, const char *type ); -- 2.47.3