summaryrefslogtreecommitdiffstats
path: root/BeOS/ar-1.1/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'BeOS/ar-1.1/main.c')
-rw-r--r--BeOS/ar-1.1/main.c312
1 files changed, 312 insertions, 0 deletions
diff --git a/BeOS/ar-1.1/main.c b/BeOS/ar-1.1/main.c
new file mode 100644
index 0000000..225ee62
--- /dev/null
+++ b/BeOS/ar-1.1/main.c
@@ -0,0 +1,312 @@
+/*
+** 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;
+}