home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
324.lha
/
AmigaLibraryManager_v1.0
/
lm.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-11-30
|
9KB
|
482 lines
#include <stdio.h>
#include "lm.h"
/* ----------------------------------------------------------------------------
LM.C
The amiga library manager.
ChangeStuff:
- Make the module buffer variable sized! maybe a command line flag...
----------------------------------------------------------------------------- */
void *AllocMem();
char *strchr();
extern void list_library();
extern void add_modules();
extern void delete_modules();
extern void replace_modules();
extern void strip_library();
extern void extract_modules();
extern void do_interactive_stuff();
long DeleteFile(), Rename(), IoErr();
long in_file, out_file;
char *get_next_file(); /* the file list parser */
FILE *list_file;
char temp_file_name[] = "lm_temp";
char new_file_name[44];
BOOL same_output_file = FALSE;
char Greeting[] =
"Amiga library manager v1.0\n\
Copyright 1988 by SLADE software\n\n";
char Usage[] =
"<input library name> <command> [output library name]\n\
Where <command> is one of the following:\n\
DELETE\t\t\t -d<module>[+module]...\n\
ADD\t\t\t -a<object-file>[+object-file]...\n\
EXTRACT\t\t\t -e<module>+[module]...\n\
STRIP SYMBOL/DEBUG HUNKS -s\n\
REPLACE\t\t\t -r<object-file>[+object-file]...\n\
LIST\t\t\t -l[list-file]\n\
INTERACTIVE MODE\t -i\n";
struct symbol *sym_list_head;
struct fname *mod_list_head;
char *in_file_name, *out_file_name;
long mod_buf[MBUF_SIZE];
long *mod_buf_ptr;
int name_count; /* count of user-supplied names */
int buffer_size; /* buffer size in longwords */
main( argc, argv )
int argc;
char **argv;
{
char **p = argv+1, *arg_string, choice;
long Open();
printf( "%s", Greeting ); /* Say hello to joe user */
if ( argc < 3 ) /* Too few arguments supplied */
{
printf( "Usage: %s %s", *argv, Usage );
my_exit( 100 );
}
/*
Parse the arguments.
*/
in_file_name = *p++; /* get pointer to input lib */
arg_string = *p; /* get pointer to arg str */
choice = tolower( *++arg_string ); /* get requested operation */
if ( argc > 3 )
out_file_name = *++p; /* get output file spec */
/*
If we are adding modules to the library, it will be created if
it does not exist. For all other operations, non-existance is
an error.
*/
if ( !( in_file = Open( in_file_name, MODE_OLDFILE ) ) )
{
if ( choice == ADD )
get_input_file( in_file_name );
else
my_exit( ENOLIB );
}
/*
Initialize dynamic lists.
*/
init_lists();
/*
First we look for commands that do not require an output file.
*/
++arg_string;
if ( choice == LIST )
{
list_library( arg_string );
my_exit( 0 );
}
if ( choice == EXTRACT )
{
extract_modules( arg_string );
my_exit( 0 );
}
open_output(); /* open output file if possible */
switch( choice )
{
case ADD : add_modules( arg_string );
break;
case DELETE : delete_modules( arg_string );
break;
case INTERACT: do_interactive_stuff();
break;
case REPLACE : replace_modules( arg_string );
break;
case STRIP : strip_library();
break;
default : my_exit( EBADOPT, arg_string );
}
/*
De-alloc all of our memory, and close the files
*/
my_exit( 0 );
}
get_input_file( in_file_name )
char *in_file_name;
{
printf( "Library File: <%s> not found, Create? (y/n) ", in_file_name );
if( tolower( getchar() ) == 'n' )
{
printf( "\nBye Bye!\n" );
my_exit( 0 );
}
printf( "\n" );
if ( !( in_file = Open( in_file_name, MODE_NEWFILE ) ) )
{
my_exit( ENOINPUT, in_file_name );
}
}
open_output()
{
/*
If there was no output file specified, or it is the same as
the input file, we will open a temp file until done, and then
replace the original file with it.
*/
char *p, *q;
if ( !out_file_name || !strcmp( in_file_name, out_file_name ) )
{
same_output_file = TRUE;
/*
If the input file name includes a device name, we must
copy it to the output file name or else Rename will not
work.
*/
if ( (p = strchr( in_file_name, ':' ) ) )
{
for( q = new_file_name, p = in_file_name; *p != ':'; )
*q++ = *p++;
*q = ':';
strcat( new_file_name, temp_file_name );
out_file_name = new_file_name;
}
else
out_file_name = temp_file_name;
}
else same_output_file = FALSE;
/*
Attempt to open the output file.
*/
if ( !( out_file = Open( out_file_name, MODE_NEWFILE ) ) )
{
my_exit( ENOOUTPUT, out_file_name );
}
}
char *get_next_file( file_list )
char *file_list;
{
static char *next_file = NULL;
static BOOL first_time = TRUE;
char *p;
/*
Return the next file in the '+' delimited file list or
NULL if no more exist.
*/
if ( first_time )
{
first_time = FALSE;
p = file_list;
}
else p = next_file;
next_file = strchr( p, '+' );
if ( *next_file )
*next_file++ = '\0';
return( p );
}
init_lists()
{
/*
Initialize the symbol and the name lists by allocating
the first nodes of each.
*/
if ( !( mod_list_head = (struct fname *)
AllocMem( (long) sizeof( struct fname ), 0L ) ) ||
!( sym_list_head = (struct symbol *)
AllocMem( (long) sizeof( struct symbol ), 0L ) ) )
{
my_exit( ENOMEM );
}
mod_list_head->next = NULL;
sym_list_head->next = NULL;
}
create_name_list( list )
char *list;
{
/*
Build a linked list out of the user supplied file list.
*/
struct fname *p = mod_list_head, *q = mod_list_head->next;
char *file_name;
/*
Fill in head node.
*/
file_name = get_next_file( list );
if ( !file_name )
{
my_exit( ENOARGS );
}
name_count = 1;
/*
Copy the file name.
*/
copy_file_name( file_name, p );
/*
Now fill in the rest of the list.
*/
while( (file_name = get_next_file( list ) ) )
{
name_count++;
if(!(q=(struct fname*)AllocMem((long)sizeof(struct fname),0L)))
{
my_exit( ENOMEM );
}
q->next = NULL;
copy_file_name( file_name, q );
/*
Hop down the list
*/
p->next = q;
p = q;
}
}
copy_file_name( file_name, list_elem )
char *file_name;
struct fname *list_elem;
{
/*
Copy both the file name and the file name without the '.' to the
record.
*/
char *p;
strcpy( list_elem->name, file_name );
strcpy( list_elem->filename, file_name );
if ( (p = strchr( list_elem->name, '.' ) ) )
*p = '\0';
}
my_exit( rc, str )
int rc;
char *str;
{
/*
Clean up the allocated memory, then quit.
*/
long Close();
if ( sym_list_head )
{
clear_sym_list();
FreeMem( sym_list_head, (long) sizeof( struct symbol ) );
}
if ( mod_list_head )
{
clear_mod_list();
FreeMem( mod_list_head, (long) sizeof( struct fname ) );
}
if ( in_file )
Close( in_file );
if ( out_file )
Close( out_file );
switch( rc )
{
case ENOINPUT: printf( "ERROR: Unable to open: <%s> \n", str );
goto error_exit;
case ENOOUTPUT: printf( "ERROR: Unable to create: <%s>\n", str );
goto error_exit;
case ENOLIST: printf( "ERROR: Unable to open list file: <%s>\n",str );
goto error_exit;
case ENOARGS: printf( "ERROR: Missing arguments\n" );
goto error_exit;
case ENOMEM: printf( "ERROR: Out of memory\n" );
goto error_exit;
case EBADOPT: printf( "ERROR: Bad option: <%ls>\n", str );
goto error_exit;
case EABORT: printf( "Aborting program...\n" );
DeleteFile( out_file_name );
exit( rc );
case ENOBUF: printf( "ERROR: Module larger than %dk\n", MBUF_SIZE/256);
goto error_exit;
case EOLIB: printf( "ERROR: End of library detected\n" );
goto error_exit;
case ENOLIB: printf( "ERROR: Library <%s> does not exist\n", in_file_name );
error_exit: DeleteFile( out_file_name );
exit( rc );
}
if ( same_output_file )
{
if ( !DeleteFile( in_file_name ) )
{
printf( "ERROR: can't delete: <%s>\nDos error code: %ld\n",
in_file_name, IoErr() );
}
if ( !Rename( out_file_name, in_file_name ) )
{
printf( "ERROR: can't rename: <%s> as: <%s>\nDos error code: %ld\n",
out_file_name, in_file_name, IoErr() );
}
}
exit( rc );
}
clear_mod_list()
{
/*
Destroy the mod list if one exists, but leave the head node
intact for future use and abuse.
*/
struct fname *p, *q = mod_list_head->next;
while ( q )
{
p = q->next;
FreeMem( q, (long) sizeof( struct fname ) );
q = p;
}
mod_list_head->next = NULL;
}
GetLongword( fp, longword )
long fp;
char *longword;
{
static char rbuf[READBUFSIZE];
static long bytes_read = 0; /* bytes read in */
static long bc = 99; /* buf counter */
register int i;
long Read();
if ( bc >= bytes_read ) /* End of the buffer */
{
if ( !( bytes_read = Read( fp, &rbuf, READBUFSIZE ) ) )
{
return( FALSE );
}
bc = 0;
}
for( i = 0; i < 4; i++, *longword++ = rbuf[bc++] ) ;
return( TRUE );
}