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 >
C/C++ Source or Header  |  1989-11-30  |  9KB  |  482 lines

  1. #include <stdio.h>
  2. #include "lm.h"
  3.  
  4. /* ----------------------------------------------------------------------------
  5.  
  6.                 LM.C
  7.  
  8. The amiga library manager.
  9.  
  10.  
  11. ChangeStuff:
  12.  
  13.     - Make the module buffer variable sized! maybe a command line flag...
  14.  
  15. ----------------------------------------------------------------------------- */
  16.  
  17. void        *AllocMem();
  18. char        *strchr();
  19.  
  20. extern    void    list_library();
  21. extern    void    add_modules();
  22. extern    void    delete_modules();
  23. extern    void    replace_modules();
  24. extern    void    strip_library();
  25. extern    void    extract_modules();
  26. extern    void    do_interactive_stuff();
  27.  
  28.  
  29. long    DeleteFile(), Rename(), IoErr();
  30. long    in_file, out_file;
  31.  
  32. char    *get_next_file();            /* the file list parser */
  33. FILE     *list_file;
  34.  
  35. char    temp_file_name[] = "lm_temp";
  36. char    new_file_name[44];
  37. BOOL    same_output_file = FALSE;
  38.  
  39. char    Greeting[] = 
  40. "Amiga library manager v1.0\n\
  41. Copyright 1988 by SLADE software\n\n";
  42.  
  43. char    Usage[] = 
  44. "<input library name> <command> [output library name]\n\
  45. Where <command> is one of the following:\n\
  46.     DELETE\t\t\t -d<module>[+module]...\n\
  47.     ADD\t\t\t -a<object-file>[+object-file]...\n\
  48.     EXTRACT\t\t\t -e<module>+[module]...\n\
  49.     STRIP SYMBOL/DEBUG HUNKS -s\n\
  50.     REPLACE\t\t\t -r<object-file>[+object-file]...\n\
  51.     LIST\t\t\t -l[list-file]\n\
  52.     INTERACTIVE MODE\t -i\n";
  53.  
  54.  
  55. struct symbol    *sym_list_head;
  56. struct fname    *mod_list_head;
  57.  
  58. char        *in_file_name, *out_file_name;
  59.  
  60. long        mod_buf[MBUF_SIZE];
  61. long        *mod_buf_ptr;
  62.  
  63. int        name_count;        /* count of user-supplied names */
  64. int        buffer_size;        /* buffer size in longwords    */
  65.  
  66.  
  67. main( argc, argv )
  68. int    argc;
  69. char    **argv;
  70.     {
  71.     char    **p = argv+1, *arg_string, choice;
  72.     long    Open();
  73.  
  74.     printf( "%s", Greeting );   /* Say hello to joe user */
  75.  
  76.     if ( argc < 3 )  /* Too few arguments supplied */
  77.         {
  78.           printf( "Usage: %s %s", *argv, Usage ); 
  79.         my_exit( 100 );
  80.         }
  81.  
  82.     /*
  83.       Parse the arguments.
  84.     */
  85.     in_file_name = *p++;            /* get pointer to input lib */
  86.     arg_string = *p;              /* get pointer to arg str   */
  87.     choice = tolower( *++arg_string );    /* get requested operation  */
  88.  
  89.     if ( argc > 3 )
  90.         out_file_name = *++p;         /* get output file spec     */
  91.  
  92.  
  93.     /*
  94.       If we are adding modules to the library, it will be created if
  95.       it does not exist. For all other operations, non-existance is
  96.       an error.
  97.     */
  98.     if ( !( in_file = Open( in_file_name, MODE_OLDFILE ) ) )
  99.         {
  100.         if ( choice == ADD )
  101.             get_input_file( in_file_name );
  102.         else
  103.             my_exit( ENOLIB );
  104.         }
  105.  
  106.     /* 
  107.       Initialize dynamic lists.
  108.     */
  109.     init_lists();
  110.         
  111.  
  112.     /*
  113.       First we look for commands that do not require an output file.
  114.     */
  115.     ++arg_string;
  116.  
  117.     if ( choice == LIST )
  118.         {
  119.         list_library( arg_string );
  120.         my_exit( 0 );
  121.         }
  122.  
  123.  
  124.     if ( choice == EXTRACT )
  125.         {
  126.         extract_modules( arg_string );        
  127.         my_exit( 0 );
  128.         }
  129.  
  130.  
  131.     open_output();        /* open output file if possible */
  132.  
  133.     switch( choice )
  134.         {
  135.         case    ADD    : add_modules( arg_string );
  136.                   break;
  137.  
  138.         case    DELETE    : delete_modules( arg_string );
  139.                   break;
  140.  
  141.         case    INTERACT: do_interactive_stuff();
  142.                   break;
  143.  
  144.         case    REPLACE : replace_modules( arg_string );
  145.                   break;
  146.  
  147.         case    STRIP    : strip_library();
  148.                   break;
  149.  
  150.         default        : my_exit( EBADOPT, arg_string );
  151.         }
  152.  
  153.     /*
  154.       De-alloc all of our memory, and close the files
  155.     */
  156.  
  157.     my_exit( 0 );
  158.     }
  159.  
  160.  
  161. get_input_file( in_file_name )
  162. char    *in_file_name;
  163.     {
  164.     printf( "Library File: <%s> not found, Create? (y/n) ", in_file_name );
  165.  
  166.     if( tolower( getchar() ) == 'n' )
  167.         {
  168.         printf( "\nBye Bye!\n" );
  169.         my_exit( 0 );
  170.         }
  171.  
  172.     printf( "\n" );
  173.  
  174.     if ( !( in_file = Open( in_file_name, MODE_NEWFILE ) ) )        
  175.         {
  176.         my_exit( ENOINPUT, in_file_name );
  177.         }
  178.     }
  179.  
  180.  
  181.  
  182. open_output()
  183.     {
  184.     /* 
  185.       If there was no output file specified, or it is the same as
  186.       the input file, we will open a temp file until done, and then 
  187.       replace the original file with it.
  188.     */
  189.  
  190.     char     *p, *q;
  191.  
  192.     if ( !out_file_name || !strcmp( in_file_name, out_file_name ) )
  193.         {
  194.         same_output_file = TRUE;
  195.  
  196.         /*
  197.           If the input file name includes a device name, we must
  198.           copy it to the output file name or else Rename will not
  199.           work.
  200.         */
  201.  
  202.         if ( (p = strchr( in_file_name, ':' ) ) )
  203.             {
  204.             for( q = new_file_name, p = in_file_name; *p != ':'; )
  205.                 *q++ = *p++;
  206.  
  207.             *q = ':';
  208.             
  209.             strcat( new_file_name, temp_file_name );
  210.             out_file_name = new_file_name;
  211.             }
  212.         else
  213.             out_file_name = temp_file_name;
  214.  
  215.         }
  216.     else    same_output_file = FALSE;
  217.  
  218.  
  219.     /* 
  220.       Attempt to open the output file.
  221.     */
  222.  
  223.     if ( !( out_file = Open( out_file_name, MODE_NEWFILE ) ) )
  224.         {
  225.         my_exit( ENOOUTPUT, out_file_name );
  226.         }
  227.  
  228.  
  229.     }        
  230.  
  231.  
  232. char *get_next_file( file_list )
  233. char    *file_list;
  234.     {
  235.     static char    *next_file = NULL;
  236.     static BOOL    first_time = TRUE;
  237.     char        *p;
  238.  
  239.     /* 
  240.       Return the next file in the '+' delimited file list or
  241.       NULL if no more exist.
  242.     */
  243.  
  244.     if ( first_time )
  245.         {
  246.         first_time = FALSE;
  247.         p = file_list;
  248.         }
  249.  
  250.     else    p = next_file;
  251.  
  252.     next_file = strchr( p, '+' );
  253.     
  254.     if ( *next_file )
  255.         *next_file++ = '\0';
  256.     
  257.     return( p );
  258.     }
  259.  
  260.  
  261. init_lists()
  262.     {
  263.     /* 
  264.       Initialize the symbol and the name lists by allocating
  265.       the first nodes of each.
  266.     */
  267.     
  268.     if ( !( mod_list_head = (struct fname *)  
  269.         AllocMem( (long) sizeof( struct fname ), 0L ) ) ||
  270.          !( sym_list_head = (struct symbol *) 
  271.             AllocMem( (long) sizeof( struct symbol ), 0L ) ) )
  272.         {
  273.         my_exit( ENOMEM );
  274.         }
  275.     
  276.     mod_list_head->next = NULL;
  277.     sym_list_head->next = NULL;
  278.     }
  279.  
  280.  
  281. create_name_list( list )
  282. char    *list;
  283.  
  284.     {
  285.     /* 
  286.       Build a linked list out of the user supplied file list.
  287.     */
  288.  
  289.     struct fname     *p = mod_list_head, *q = mod_list_head->next;
  290.     char        *file_name;
  291.  
  292.     /* 
  293.       Fill in head node.
  294.     */
  295.     file_name = get_next_file( list );
  296.     if ( !file_name )
  297.         {
  298.         my_exit( ENOARGS );
  299.         }
  300.  
  301.  
  302.     name_count = 1;    
  303.  
  304.     /* 
  305.       Copy the file name.
  306.     */
  307.     copy_file_name( file_name, p );
  308.  
  309.     /* 
  310.       Now fill in the rest of the list.
  311.     */
  312.     while( (file_name = get_next_file( list ) ) )
  313.         {
  314.         name_count++;
  315.  
  316.         if(!(q=(struct fname*)AllocMem((long)sizeof(struct fname),0L)))
  317.             {
  318.             my_exit( ENOMEM );
  319.             }
  320.         q->next = NULL;
  321.         
  322.         copy_file_name( file_name, q );
  323.  
  324.         /*
  325.           Hop down the list
  326.         */
  327.         p->next = q;
  328.         p = q;
  329.         }
  330.     }
  331.  
  332.  
  333. copy_file_name( file_name, list_elem )
  334. char        *file_name;
  335. struct fname    *list_elem;
  336.  
  337.     {
  338.     /*
  339.       Copy both the file name and the file name without the '.' to the
  340.       record.
  341.     */
  342.     char    *p;
  343.  
  344.     strcpy( list_elem->name, file_name );
  345.     strcpy( list_elem->filename, file_name );
  346.     
  347.     if ( (p = strchr( list_elem->name, '.' ) ) )
  348.         *p = '\0';
  349.     }
  350.  
  351.  
  352. my_exit( rc, str )
  353. int    rc;
  354. char    *str;
  355.  
  356.     {
  357.     /* 
  358.       Clean up the allocated memory, then quit.
  359.     */
  360.     long    Close();
  361.  
  362.     if ( sym_list_head )
  363.         {
  364.         clear_sym_list();
  365.         FreeMem( sym_list_head, (long) sizeof( struct symbol ) );
  366.         }
  367.  
  368.     if ( mod_list_head )
  369.         {
  370.         clear_mod_list();
  371.         FreeMem( mod_list_head, (long) sizeof( struct fname ) );
  372.         }
  373.  
  374.     if ( in_file )
  375.         Close( in_file );
  376.  
  377.     if ( out_file )
  378.         Close( out_file );
  379.  
  380.     
  381.     switch( rc )
  382.     {
  383.     case    ENOINPUT:  printf( "ERROR: Unable to open: <%s> \n", str  );
  384.                goto error_exit;
  385.  
  386.     case    ENOOUTPUT: printf( "ERROR: Unable to create: <%s>\n", str );
  387.                goto error_exit;
  388.  
  389.     case    ENOLIST:   printf( "ERROR: Unable to open list file: <%s>\n",str );
  390.                    goto error_exit;
  391.  
  392.     case    ENOARGS:   printf( "ERROR: Missing arguments\n" );
  393.                goto error_exit;
  394.  
  395.      case    ENOMEM:       printf( "ERROR: Out of memory\n" );
  396.                goto error_exit;
  397.  
  398.      case    EBADOPT:   printf( "ERROR: Bad option: <%ls>\n", str );
  399.                goto error_exit;
  400.                
  401.     case    EABORT:       printf( "Aborting program...\n" );
  402.                DeleteFile( out_file_name );
  403.                exit( rc );
  404.  
  405.     case    ENOBUF:    printf( "ERROR: Module larger than %dk\n", MBUF_SIZE/256);
  406.                goto error_exit;
  407.  
  408.     case    EOLIB:     printf( "ERROR: End of library detected\n" );
  409.                goto error_exit;
  410.  
  411.     case    ENOLIB:       printf( "ERROR: Library <%s> does not exist\n", in_file_name );
  412.                
  413.     error_exit:       DeleteFile( out_file_name );
  414.                exit( rc );
  415.     }
  416.  
  417.     if ( same_output_file )
  418.         {
  419.         if ( !DeleteFile( in_file_name ) )
  420.             {
  421.             printf( "ERROR: can't delete: <%s>\nDos error code: %ld\n", 
  422.             in_file_name, IoErr() );
  423.             }
  424.  
  425.         if ( !Rename( out_file_name, in_file_name ) ) 
  426.             {
  427.             printf( "ERROR: can't rename: <%s> as: <%s>\nDos error code: %ld\n", 
  428.             out_file_name, in_file_name, IoErr() );
  429.             }
  430.         }
  431.  
  432.     exit( rc );
  433.     }
  434.  
  435.  
  436. clear_mod_list()
  437.     {
  438.     /* 
  439.       Destroy the mod list if one exists, but leave the head node 
  440.       intact for future use and abuse.
  441.     */
  442.  
  443.     struct fname    *p, *q = mod_list_head->next;
  444.  
  445.     while ( q )
  446.         {
  447.         p = q->next;
  448.         
  449.         FreeMem( q, (long) sizeof( struct fname ) );
  450.         q = p;
  451.         }        
  452.  
  453.     mod_list_head->next = NULL;
  454.     }
  455.  
  456.  
  457.  
  458. GetLongword( fp, longword )
  459. long    fp;
  460. char    *longword;
  461.  
  462.     {
  463.     static char    rbuf[READBUFSIZE];
  464.     static long    bytes_read = 0;        /* bytes read in */
  465.     static long    bc = 99;        /* buf counter */
  466.     register    int i;
  467.     long        Read();
  468.  
  469.     if ( bc >= bytes_read )    /* End of the buffer */
  470.         {
  471.         if ( !( bytes_read = Read( fp, &rbuf, READBUFSIZE ) ) )
  472.             {
  473.             return( FALSE );
  474.             }
  475.         bc = 0;
  476.         }
  477.  
  478.     for( i = 0; i < 4; i++, *longword++ = rbuf[bc++] ) ;
  479.  
  480.     return( TRUE );
  481.     }
  482.