diff options
-rw-r--r-- | BeOS/ar-1.1/Makefile | 48 | ||||
-rw-r--r-- | BeOS/ar-1.1/README.html | 1 | ||||
-rw-r--r-- | BeOS/ar-1.1/README.txt | 29 | ||||
-rw-r--r-- | BeOS/ar-1.1/ar | bin | 16355 -> 0 bytes | |||
-rw-r--r-- | BeOS/ar-1.1/ar.xMAP | 461 | ||||
-rw-r--r-- | BeOS/ar-1.1/commands.c | 809 | ||||
-rw-r--r-- | BeOS/ar-1.1/commands.h | 28 | ||||
-rw-r--r-- | BeOS/ar-1.1/copy_attrs.c | 128 | ||||
-rw-r--r-- | BeOS/ar-1.1/copy_attrs.h | 24 | ||||
-rw-r--r-- | BeOS/ar-1.1/docs/ar.html | 234 | ||||
-rw-r--r-- | BeOS/ar-1.1/docs/dumpar.py | 271 | ||||
-rw-r--r-- | BeOS/ar-1.1/docs/dumpo.py | 126 | ||||
-rw-r--r-- | BeOS/ar-1.1/docs/notes | 34 | ||||
-rw-r--r-- | BeOS/ar-1.1/main.c | 312 | ||||
-rw-r--r-- | BeOS/ar-1.1/mwlib.c | 711 | ||||
-rw-r--r-- | BeOS/ar-1.1/mwlib.h | 118 |
16 files changed, 0 insertions, 3334 deletions
diff --git a/BeOS/ar-1.1/Makefile b/BeOS/ar-1.1/Makefile deleted file mode 100644 index 8fb11ec..0000000 --- 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 607c03a..0000000 --- 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 f995789..0000000 --- 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 Binary files differdeleted file mode 100644 index e44e2dc..0000000 --- a/BeOS/ar-1.1/ar +++ /dev/null diff --git a/BeOS/ar-1.1/ar.xMAP b/BeOS/ar-1.1/ar.xMAP deleted file mode 100644 index bee438d..0000000 --- a/BeOS/ar-1.1/ar.xMAP +++ /dev/null @@ -1,461 +0,0 @@ -File: 0 "/boot/src/ar-1.0/main.c" -File: 1 "/boot/src/ar-1.0/mwlib.c" -File: 2 "/boot/src/ar-1.0/commands.c" -File: 3 "/boot/src/ar-1.0/copy_attrs.c" -File: 5 "/boot/rel/src/kit/glue/common/global_destructor_chain.c" -File: 6 "/boot/rel/src/kit/glue/ppc/runtime.c" -File: 9 "/boot/rel/src/kit/glue/common/init_term_dyn.c" -File: 10 "/boot/rel/src/kit/glue/common/start_dyn.c" -File: 11 "/boot/develop/lib/ppc/libroot.so" - -Files that were not referenced: -"libbe.so" -"libtracker.so" -"libmedia.so" -"libnet.so" -"libnetdev.so" -"libdevice.so" -"libmidi.so" -"libgame.so" -"libatalk.so" -"libmail.so" - -Code section, size = 16672 bytes -000000 PR .__sinit file = "*Linker-Generated*" -00001C PR .usage file = "main.c" -000050 PR .version -000094 PR .check_command -000128 PR .main -0005A0 PR .load_MW_lib file = "mwlib.c" -000A1C PR .load_MWLibFile -000BAC PR .fwrite_big32 -000C10 PR .fwrite_big32_seek -000CA4 PR .add_object_sizes -000DA4 PR .setfiletype -000EA8 PR .write_MW_lib -001850 PR .do_match file = "commands.c" -001958 PR .do_delete -001A84 PR .delete_lib_entry -001C5C PR .do_print -001D98 PR .print_lib_entry -001E90 PR .load_lib_file -0020F4 PR .do_replace -0023B8 PR .add_lib_entry -00256C PR .replace_lib_entry -00272C PR .do_table -002868 PR .table_lib_entry -0029E8 PR .do_extract -002B24 PR .extract_lib_entry -002E20 PR .copy_attrs file = "copy_attrs.c" -00306C PR .__destroy_global_chain file = "global_destructor_chain.c" -0030C0 PR .__RTOC file = "init_term_dyn.c" -0030C8 PR ._init_routine_ -003118 PR ._term_routine_ -003148 PR .__start file = "start_dyn.c" -003204 GL .__register_fragment file = "*Linker-Generated*" -00321C GL .find_thread -003234 GL .memcpy -00324C GL ._call_init_routines_ -003264 GL .printf -00327C GL .exit -003294 GL .getopt -0032AC GL .malloc -0032C4 GL .__assertion_failed -0032DC GL .fprintf -0032F4 GL .fopen -00330C GL .fread -003324 GL .fseek -00333C GL .fgets -003354 GL .strdup -00336C GL .fclose -003384 GL .strrchr -00339C GL .strcmp -0033B4 GL .free -0033CC GL .memset -0033E4 GL .access -0033FC GL .stat -003414 GL ._errnop -00342C GL .strerror -003444 GL .strlen -00345C GL .sprintf -003474 GL .unlink -00348C GL .rename -0034A4 GL .fwrite -0034BC GL .ftell -0034D4 GL .chmod -0034EC GL .open -003504 GL .close -00351C GL .fs_fopen_attr_dir -003534 GL .fs_read_attr_dir -00354C GL .fs_stat_attr -003564 GL .fs_read_attr -00357C GL .fs_write_attr -003594 GL .fflush -0035AC GL .realloc -0035C4 GL .localtime -0035DC GL .strftime -0035F4 GL .getgid -00360C GL .getuid -003624 GL .utime -00363C GL ._thread_do_exit_notification -003654 GL .__unregister_fragment -00366C GL .__ptr_glue file = "runtime.c" -003680 RO @10 file = "main.c" -003690 RO @13 -0036B4 RO @16 -0036D8 RO @17 -0036FC RO @18 -003739 RO @30 -003769 RO @109 -00378A RO @110 -0037A2 RO @111 -0037BA RO @112 -0037D3 RO @113 -0037DD RO @114 -0037FD RO @115 -003815 RO @116 -003829 RO @117 -00383D RO @118 -003871 RO @119 -00388C RO @120 -0038A5 RO @121 -0038B9 RO @78 file = "mwlib.c" -0038C3 RO @79 -0038CB RO @80 -0038DA RO @81 -0038DC RO @98 -0038E7 RO @99 -0038F5 RO @104 -0038FE RO @122 -003908 RO @123 -003913 RO @124 -00391E RO @133 -003947 RO @134 -003951 RO @135 -00397B RO @235 -003980 RO @236 -0039AC RO @237 -0039C3 RO @238 -0039F5 RO @239 -0039F9 RO @240 -003A12 RO @241 -003A33 RO @242 -003A35 RO @243 -003A56 RO @244 -003A7B RO @245 -003AA7 RO @246 -003AD1 RO @247 -003AF0 RO @248 -003B14 RO @249 -003B3D RO @250 -003B69 RO @251 -003B90 RO @252 -003BBB RO @253 -003BD8 RO @254 -003BF1 RO @255 -003C11 RO @29 file = "commands.c" -003C1B RO @30 -003C26 RO @31 -003C31 RO @32 -003C3B RO @53 -003C4E RO @54 -003C65 RO @55 -003C7D RO @81 -003C9E RO @82 -003CA6 RO @120 -003CAE RO @121 -003CC5 RO @142 -003CD4 RO @143 -003CDF RO @144 -003CF6 RO @145 -003D0C RO @146 -003D2E RO @147 -003D30 RO @148 -003D47 RO @149 -003D5E RO @198 -003D6F RO @199 -003D89 RO @200 -003DAA RO @222 -003DCF RO @223 -003DE8 RO @224 -003E12 RO @225 -003E1A RO @242 -003E39 RO @243 -003E65 RO @244 -003E6D RO @284 -003E85 RO @285 -003E88 RO @286 -003E9F RO @287 -003EBE RO @288 -003EC9 RO @289 -003ECD RO @343 -003EE6 RO @344 -003EEE RO @345 -003EF0 RO @346 -003F11 RO @347 -003F27 RO @348 -003F53 RO @349 -003F7E RO @350 -003F97 RO @43 file = "copy_attrs.c" -003FA6 RO @44 -003FB3 RO @45 -003FC4 TI @14 file = "main.c" -003FD0 TI @19 -003FDC TI @32 -003FE8 TI @124 -003FF4 TI @82 file = "mwlib.c" -004000 TI @100 -00400C TI @105 -004018 TI @111 -004024 TI @125 -004030 TI @136 -00403C TI @256 -004048 TI @33 file = "commands.c" -004054 TI @56 -004060 TI @83 -00406C TI @110 -004078 TI @122 -004084 TI @150 -004090 TI @201 -00409C TI @226 -0040A8 TI @245 -0040B4 TI @272 -0040C0 TI @290 -0040CC TI @317 -0040D8 TI @351 -0040E4 TI @46 file = "copy_attrs.c" -0040F0 TI @7 file = "global_destructor_chain.c" -0040FC TI @2 file = "init_term_dyn.c" -004108 TI @4 -004114 TI @17 file = "start_dyn.c" - -Data section, size = 1084 bytes (TOC anchor = 000000) -000000 TC fs_write_attr file = "*Linker-Generated*" -000004 TC strftime -000008 TC fwrite -00000C TC sprintf -000010 TC open -000014 TC fread -000018 TC fs_fopen_attr_dir -00001C TC fseek -000020 TC strrchr -000024 TC free -000028 TC printf -00002C TC ftell -000030 TC exit -000034 TC strerror -000038 TC __register_fragment -00003C TC memcpy -000040 TC strcmp -000044 TC strlen -000048 TC _call_init_routines_ -00004C TC strdup -000050 TC _files -000054 TC fgets -000058 TC malloc -00005C TC find_thread -000060 TC close -000064 TC memset -000068 TC chmod -00006C TC fopen -000070 TC stat -000074 TC fs_read_attr -000078 TC access -00007C TC fs_read_attr_dir -000080 TC unlink -000084 TC getopt -000088 TC getgid -00008C TC __unregister_fragment -000090 TC _errnop -000094 TC fprintf -000098 TC optind -00009C TC __assertion_failed -0000A0 TC rename -0000A4 TC utime -0000A8 TC getuid -0000AC TC fs_stat_attr -0000B0 TC fflush -0000B4 TC _thread_do_exit_notification -0000B8 TC fclose -0000BC TC localtime -0000C0 TC realloc -0000C4 TC __global_destructor_chain -0000C8 TC __exception_table_end__ -0000CC TC __exception_table_start__ -0000D0 TC __data_end__ -0000D4 TC __data_start__ -0000D8 TC __code_end__ -0000DC TC __code_start__ -0000E0 TC __main_thread_id -0000E4 TC environ -0000E8 TC argv_save -0000EC TC @123 file = "main.c" -0000F0 TC @122 -0000F4 TC @121 -0000F8 TC @120 -0000FC TC @119 -000100 TC @118 -000104 TC @117 -000108 TC @116 -00010C TC @115 -000110 TC @114 -000114 TC @113 -000118 TC @112 -00011C TC @111 -000120 TC @110 -000124 TC @109 -000128 TC @31 -00012C TC @30 -000130 TC @18 -000134 TC @17 -000138 TC @16 -00013C TC @13 -000140 TC @255 file = "mwlib.c" -000144 TC @254 -000148 TC @253 -00014C TC @252 -000150 TC @251 -000154 TC @250 -000158 TC @249 -00015C TC @248 -000160 TC @247 -000164 TC @246 -000168 TC @245 -00016C TC @244 -000170 TC @243 -000174 TC @242 -000178 TC @241 -00017C TC @240 -000180 TC @239 -000184 TC @238 -000188 TC @237 -00018C TC @236 -000190 TC @235 -000194 TC @135 -000198 TC @134 -00019C TC @133 -0001A0 TC @124 -0001A4 TC @123 -0001A8 TC @122 -0001AC TC @104 -0001B0 TC @99 -0001B4 TC @98 -0001B8 TC @81 -0001BC TC @80 -0001C0 TC @79 -0001C4 TC @78 -0001C8 TC @350 file = "commands.c" -0001CC TC @349 -0001D0 TC @348 -0001D4 TC @347 -0001D8 TC @346 -0001DC TC @345 -0001E0 TC @344 -0001E4 TC @343 -0001E8 TC @289 -0001EC TC @288 -0001F0 TC @287 -0001F4 TC @286 -0001F8 TC @285 -0001FC TC @284 -000200 TC @244 -000204 TC @243 -000208 TC @242 -00020C TC @225 -000210 TC @224 -000214 TC @223 -000218 TC @222 -00021C TC @200 -000220 TC @199 -000224 TC @198 -000228 TC @149 -00022C TC @148 -000230 TC @147 -000234 TC @146 -000238 TC @145 -00023C TC @144 -000240 TC @143 -000244 TC @142 -000248 TC @121 -00024C TC @120 -000250 TC @82 -000254 TC @81 -000258 TC @55 -00025C TC @54 -000260 TC @53 -000264 TC @32 -000268 TC @31 -00026C TC @30 -000270 TC @29 -000274 TC @45 file = "copy_attrs.c" -000278 TC @44 -00027C TC @43 -000280 TC magic_template file = "start_dyn.c" -000284 TC default_environ -000288 TD ar_version_id file = "main.c" -00028C TD fragmentID file = "init_term_dyn.c" -000290 DS _term_routine_ file = "init_term_dyn.c" -000298 DS _init_routine_ -0002A0 DS __start file = "start_dyn.c" -0002A8 RW @31 file = "main.c" -0002FC RW @123 -000388 RW @122 -000414 RW magic_template file = "start_dyn.c" -00041C RW @13 -00042C RW default_environ -000434 RW __global_destructor_chain file = "global_destructor_chain.c" - -Import container "libroot.so" -Current Version = 00000000, Old Implementation = 00000000 -000000 DS fs_write_attr -000001 DS strftime -000002 DS fwrite -000003 DS sprintf -000004 DS open -000005 DS fread -000006 DS fs_fopen_attr_dir -000007 DS fseek -000008 DS strrchr -000009 DS free -00000A RW environ -00000B DS printf -00000C DS ftell -00000D DS exit -00000E DS strerror -00000F DS __register_fragment -000010 DS memcpy -000011 DS strcmp -000012 DS strlen -000013 DS _call_init_routines_ -000014 DS strdup -000015 RW argv_save -000016 RW _files -000017 DS fgets -000018 DS malloc -000019 DS find_thread -00001A DS close -00001B DS memset -00001C DS chmod -00001D DS fopen -00001E DS stat -00001F DS fs_read_attr -000020 DS access -000021 DS fs_read_attr_dir -000022 DS unlink -000023 DS getopt -000024 DS getgid -000025 DS __unregister_fragment -000026 DS _errnop -000027 DS fprintf -000028 RW optind -000029 DS __assertion_failed -00002A DS rename -00002B DS utime -00002C RW __main_thread_id -00002D DS getuid -00002E DS fs_stat_attr -00002F DS fflush -000030 DS _thread_do_exit_notification -000031 DS fclose -000032 DS localtime -000033 DS realloc diff --git a/BeOS/ar-1.1/commands.c b/BeOS/ar-1.1/commands.c deleted file mode 100644 index f9304d0..0000000 --- a/BeOS/ar-1.1/commands.c +++ /dev/null @@ -1,809 +0,0 @@ -/* -** commands.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 <support/Errors.h> -#include <support/byteorder.h> -#ifndef NO_DEBUG -#include <assert.h> -#define ASSERT(cond) assert(cond) -#else -#define ASSERT(cond) ((void)0) -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <limits.h> -#include <string.h> -#include <utime.h> -#include <errno.h> -#include <sys/stat.h> - -#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 e5c28c2..0000000 --- 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 <be/support/SupportDefs.h> - -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 c9f978d..0000000 --- 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 <support/Errors.h> -#ifndef NO_DEBUG -#include <assert.h> -#define ASSERT(cond) assert(cond) -#else -#define ASSERT(cond) ((void)0) -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <limits.h> -#include <string.h> -#include <errno.h> -#include <kernel/fs_attr.h> -#include <fcntl.h> - -#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 a761636..0000000 --- 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 50f002e..0000000 --- a/BeOS/ar-1.1/docs/ar.html +++ /dev/null @@ -1,234 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML3.2//EN"> -<!-- $Id$ --> -<html> <head> -<title>ar - create and maintain library archives</title> -</head> - -<body bgcolor="#ffffcb"> -<h1>ar</h1> -<h4 align="right">create and maintain library archives</h4> - -<h2>Synopsis</h2> - -<pre> -ar [-][dprtx][cuv] <i>archive</i> [<i>file</i> ...] -</pre> - -<h2>Options</h2> - -<table> -<tr> - <td valign="top"><b>-</b></td> - <td valign="top"> - The <b>-</b> is optional for introducing <tt>ar</tt> command-line - arguments; this is a POSIX requirement, and I've never seen anyone - use it.</td> -</tr> - -<tr> - <td valign="top"><b>c</b></td> - <td valign="top"> - Don't print a diagnostic message to <i>stderr</i> when - <i>archive</i> is created.</td> -</tr> - -<tr> - <td valign="top"><b>d</b></td> - <td valign="top"> - Delete <i>file(s)</i> from <i>archive</i>.</td> -</tr> - -<tr> - <td valign="top"><b>p</b></td> - <td valign="top"> - Write the contents of the named <i>file(s)</i> to <i>stdout</i>. - If no <i>file(s)</i> are specified, all of the files in - <i>archive</i> are written in the order of the archive.</td> -</tr> - -<tr> - <td valign="top"><b>r</b></td> - <td valign="top"> - Replace or add <i>file(s)</i> to the <i>archive</i>. This will - create <i>archive</i> if it doesn't already exist.</td> -</tr> - -<tr> - <td valign="top"><b>t</b></td> - <td valign="top"> - Write the table of contents of <i>archive</i> to <i>stdout</i>. - If not <i>file(s)</i> are specified, list all of the files, - otherwise only list the specified files.</td> -</tr> - -<tr> - <td valign="top"><b>u</b></td> - <td valign="top"> - Update older files. When used with the <b>r</b> option, files - within the archive are only replaced if <i>file</i> has a - modification date at least as new as the <i>file</i> already in - the archive.</td> -</tr> - -<tr> - <td valign="top"><b>v</b></td> - <td valign="top">Give verbose output.</td> -</tr> - -<tr> - <td valign="top"><b>x</b></td> - <td valign="top"> - Extract <i>file(s)</i> from the <i>archive</i>. If no - <i>file(s)</i> are specified, all of the files in <i>archive</i> - are extracted.</td> -</tr> - -<tr> - <td valign="top"><i>archive</i></td> - <td valign="top"> - The pathname of an archive file.</td> -</tr> - -<tr> - <td valign="top"><i>file</i></td> - <td valign="top"> - One more more pathnames of object files; only the file name is - used when comparing against the names of files in the - archive.</td> -</tr> - -</table> - -<h2>Description</h2> - -<p>The <tt>ar</tt> 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.</p> - -<h2>Exit status</h2> - -<p><tt>ar</tt> exits with one of the following values:</p> - -<table> -<tr><td valign="top">0</td> - <td valign="top">Successful completion.</td></tr> -<tr><td valign="top">> 0</td> - <td>An error occurred.</td></tr> -</table> - -<h2>Bugs</h2> - -<p>No known bugs, but <em>please</em> read the comments in the code if -you want to use it in another application.</p> - -<h2>Comments</h2> - -<p>This is a POSIX 1003.2-1992 based <tt>ar</tt> command; it's not -100% POSIX 1003.2 because POSIX specifies a file format for -<tt>ar</tt> archives. The BeOS <tt>ar</tt> produces library files -compatible (at least in theory <tt>:-)</tt>) with Metrowerks -CodeWarrior for PowerPC.</p> - -<p>This <tt>ar</tt> 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).</p> - -<p>If you find this useful, please -<a href="mailto:chrish@kagi.com">let me know</a>, and tell me what -you're working on. Be sure to include a URL for your homepage or your -product homepages for my -<a href="http://www.qnx.com/~chrish/Be/community/">Be Community</a> -pages.</p> - -<p>If you find any bugs, please try to fix them, and send me a context -diff (use <tt>diff -c original_file fixed_file</tt>) so I can include -your fixes in the next update. I <i>have</i> tested this, but these -things have a way of slipping though.</p> - -<p>If you'd like to know what other things I'm working on, take a look -at my <a href="http://www.qnx.com/~chrish/Be/software/">Be -Software</a> pages, and my -<a href="http://www.qnx.com/~chrish/Be/">Be Happy!</a> pages.</p> - -<h2>License</h2> - -<p>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.</p> - -<p>If you <em>really</em> 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!), <i>etc.</i> -Send me some <a href="mailto:chrish@kagi.com">email</a> and I'll let you -know where to send it.</p> - -<p>But you don't have to do anything. Just write good BeOS software. -But you're already doing that, right?</p> - -<h2>Disclaimer</h2> - -<p>You use this at your own risk. I've tried to ensure that the code -is correct, but software usually has bugs. If <tt>ar</tt> 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.</p> - -<p>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.</p> - -<h3>A word about the code</h3> - -<p>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.</p> - -<p>If you think this code sucks, don't use it. You're already applying -this to your choice of operating system! <tt>:-)</tt></p> - -<h2>Versions</h2> - -<dl compact> - -<dt><strong>1.1 (April 18, 1998)</strong></dt> -<dd>Changes include: - <ul> - <li>Extract option (<b>x</b>) will preserve a file's mode bits - when overwriting an existing file (this may go away if it's - not POSIX behaviour).</li> - - <li>Extracted files will now have the proper file type.</li> - - <li>Removed attempt to use <i>umask()</i> to set newly created - archive's mode bits; apparently, I'm not sure how it - works and my POSIX manual isn't helping.</li> - - <li>Should be 100% endian-neutral now; using this on BeOS for - x86 is only useful if you're manipulating <em>PowerPC</em> - objects though. The <tt>ar</tt> in - <a href="http://www.ninemoons.com/GG/index.html">GeekGadgets</a> - should work fine for x86 objects/libraries.</li> - - <li>Updated the <tt>README.txt</tt> file; now it's got useful - information about building/using the POSIX ar.</li> - </ul></dd> - -<dt><strong>1.0 (January 13, 1998)</strong></dt> -<dd>Initial release.</dd> - -</dl> - -<hr> -<p>Chris Herborth (<a href="mailto:chrish@qnx.com">chrish@qnx.com</a>)</p> -<!-- hhmts start --> -Last modified: $Date$ -<!-- hhmts end --> -</body> </html> diff --git a/BeOS/ar-1.1/docs/dumpar.py b/BeOS/ar-1.1/docs/dumpar.py deleted file mode 100644 index 93e2283..0000000 --- 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 91bd8db..0000000 --- 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 4a90a16..0000000 --- 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 225ee62..0000000 --- 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 <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <getopt.h> - -#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 f3b8660..0000000 --- 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 <support/Errors.h> -#include <support/byteorder.h> -#ifndef NO_DEBUG -#include <assert.h> -#define ASSERT(cond) assert(cond) -#else -#define ASSERT(cond) ((void)0) -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <limits.h> -#include <string.h> -#include <errno.h> -#include <kernel/fs_attr.h> -#include <fcntl.h> /* is open() really here?!? sheesh... */ -#include <storage/Mime.h> -#include <sys/stat.h> - -#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 67af325..0000000 --- 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 <support/SupportDefs.h> -#include <time.h> - -/* ---------------------------------------------------------------------- -** 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 ); |