home *** CD-ROM | disk | FTP | other *** search
/ Beijing Paradise BBS Backup / PARADISE.ISO / software / BBSDOORW / MAM100.ZIP / MAMOVE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1994-05-22  |  10.6 KB  |  345 lines

  1. /*********************************************************************
  2. ** FILENAME: mamove.c                       VERSION: 1.00
  3. **
  4. ** DESCRIPTION: RemoteAccess message area positioning utility
  5. **
  6. ** NOTES: See wb_fcopy.c for file_copy() details.
  7. **
  8. ** AUTHOR: John Kristoff                START DATE: 04/29/94
  9. **         Internet: jkristof@xroads.chigate.com
  10. **                   jkristof@mica.meddean.luc.edu
  11. **         FidoNet:  1:115/743
  12. **      CompuServe:  74111,3652
  13. **
  14. ** VERSION  DATE     WHO  DETAIL
  15. ** 1.00     22May94  JK   Initial design and coding
  16. **
  17. **      Copyright John Kristoff, 1994.  All rights reserved.
  18. **      You may use this program or any part there-of as desired
  19. **      without restriction.
  20. */
  21.  
  22. #include <stdio.h>                      /* Standard i/o */
  23. #include <stdlib.h>                     /* Standard library */
  24. #include <limits.h>                     /* Variable max/min macros */
  25. #include "ra.h"                         /* RemoteAccess structures */
  26. #include "wb_fcopy.c"                   /* Copy a file */
  27.  
  28. #define VERS       "1.00"               /* Version of this program */
  29. #define FNAME      "MESSAGES.RA"        /* Data file */
  30. #define FNAMEBAK   "MESSAGES.BAK"       /* Backup data file */
  31. #define FNAMELEN   81                   /* Fully qualified filepath + '\0' */
  32. #define AREALEN    40                   /* Message area string length */
  33. #define ENVVAR     "RA"                 /* Environment variable of RA dir */
  34. #define FALSE      0                    /* Boolean false flag */
  35. #define TRUE       1                    /* Boolean true flag */
  36.  
  37. #define HELP       1                    /* Display help screen */
  38. #define OPEN       10                   /* Error opening file */
  39. #define CLOSE      20                   /* Error closing file */
  40. #define READ       30                   /* Error reading file */
  41. #define WRITE      40                   /* Error writing file */
  42. #define SEEK       50                   /* Error seeking in file */
  43. #define MEMORY     60                   /* Error allocating memory */
  44.  
  45. #define USAGE      "   Usage:  MAMOVE <source> <dest>\n"\
  46.                    "Examples:  MAMOVE 23 2, MAMOVE 15 382, MAMOVE 1 6\n"\
  47.                    "\n"\
  48.                    "<source>   area # to move\n"\
  49.                    "  <dest>   area # <source> will precede\n"\
  50.                    "\n"\
  51.                    "   Note:   area # range is 1 to %ld\n", LONG_MAX
  52.  
  53. int main( int argc, char * argv[] );    /* If you don't know, YUSC */
  54. void Error( int ErrorLevel,             /* Error handling function */
  55.             int Line,
  56.             char * Filename );
  57.  
  58. int
  59. main( int argc, char * argv[] )
  60. {
  61.     long int AreaToMove  = 0;           /* Area # to be moved */
  62.     long int CurrentArea = 0;           /* The Area # we're at */
  63.     long int InsertPoint = 0;           /* AreaToMove placed before this */
  64.     long int SeekPoint   = 0;           /* How many structs til MoveArea */
  65.  
  66.     int Moved = FALSE;                  /* Flag trips when area is moved */
  67.  
  68.     struct MESSAGE MoveArea;            /* Structure to be moved */
  69.     struct MESSAGE Area;                /* Current struct in processing */
  70.  
  71.     char * DataDir = NULL;              /* Pointer to ENVVAR */
  72.     char Filename[FNAMELEN] = FNAME;    /* Fully qualified data filename */
  73.     char BakFile[FNAMELEN]  = FNAMEBAK; /* Fully qualified backup filename */
  74.  
  75.     FILE * fpFilename = NULL;           /* Pointer to data file */
  76.     FILE * fpBakFile  = NULL;           /* Pointer to backup data file */
  77.  
  78.     printf( "\n"
  79.             "MAMOVE v" VERS ", " __DATE__ ".\n"
  80.             "RemoteAccess message area positioning utility\n"
  81.             "Copyright John Kristoff, 1994.  All rights reserved.\n"
  82.             "\n" );
  83.  
  84.     if( argc < 3 )
  85.     {
  86.         Error( HELP, __LINE__, NULL );
  87.     }
  88.  
  89.     /*
  90.     ** Build fully qualified filenames if ENVVAR exists.
  91.     */
  92.     if( (DataDir = getenv(ENVVAR)) != NULL )
  93.     {
  94.         if( DataDir[strlen(DataDir) - 1] != '\\')
  95.         {
  96.             sprintf( Filename, "%s\\%s", DataDir, FNAME );
  97.             sprintf( BakFile, "%s\\%s", DataDir, FNAMEBAK );
  98.         }
  99.         else
  100.         {
  101.             sprintf( Filename, "%s%s", DataDir, FNAME );
  102.             sprintf( BakFile, "%s%s", DataDir, FNAMEBAK );
  103.         }
  104.     }
  105.  
  106.     /*
  107.     ** Get area to be moved.
  108.     */
  109.     AreaToMove  = atol( argv[1] );
  110.     if( AreaToMove < 1 || AreaToMove > LONG_MAX )
  111.     {
  112.         Error( HELP, __LINE__, NULL );
  113.     }
  114.  
  115.     /*
  116.     ** Get insertion point of area to be moved.
  117.     */
  118.     InsertPoint = atol( argv[2] );
  119.     if( InsertPoint < 1 || InsertPoint > LONG_MAX )
  120.     {
  121.         Error( HELP, __LINE__, NULL );
  122.     }
  123.  
  124.     /*
  125.     ** Make backup of data file.
  126.     */
  127.     if( file_copy( Filename, BakFile ) == 1 )
  128.     {
  129.         fprintf( stderr, "ERROR (%d): Cannot copy %s to %s\n",
  130.                          __LINE__, Filename, BakFile );
  131.         exit( EXIT_FAILURE );
  132.     }
  133.  
  134.     /*
  135.     ** We'll be reading from the backup file in order to re-create
  136.     ** a new data file.
  137.     */
  138.     fpBakFile = fopen( BakFile, "rb" );
  139.     if( fpBakFile == NULL )
  140.     {
  141.         Error( OPEN, __LINE__, BakFile );
  142.     }
  143.  
  144.     /*
  145.     ** Go to the area to move and read struct.
  146.     */
  147.     SeekPoint = sizeof(struct MESSAGE) * ( AreaToMove - 1 );
  148.     if( fseek(fpBakFile, SeekPoint, SEEK_SET) != 0 )
  149.     {
  150.         Error( SEEK, __LINE__, BakFile );
  151.     }
  152.  
  153.     if( fread(&MoveArea, sizeof(struct MESSAGE), 1, fpBakFile) == NULL )
  154.     {
  155.         Error( READ, __LINE__, BakFile );
  156.     }
  157.  
  158.     rewind( fpBakFile );
  159.  
  160.     fpFilename = fopen( Filename, "wb" );
  161.     if( fpFilename == NULL )
  162.     {
  163.         Error( OPEN, __LINE__, Filename );
  164.     }
  165.  
  166.     if( fread(&Area, sizeof(struct MESSAGE), 1, fpBakFile) == NULL )
  167.     {
  168.         Error( READ, __LINE__, BakFile );
  169.     }
  170.  
  171.     /*
  172.     ** Read backup data file until EOF, writing new data file as we go.
  173.     */
  174.     while( !feof(fpBakFile) )
  175.     {
  176.         ++CurrentArea;
  177.  
  178.         /*
  179.         ** If this is the insertion point, add the area to move.
  180.         */
  181.         if( CurrentArea == InsertPoint )
  182.         {
  183.             /*
  184.             ** Blank area name strings that are reported to stdout.
  185.             */
  186.             char MoveName[AREALEN + 1]   = "";
  187.             char InsertName[AREALEN + 1] = "";
  188.  
  189.             /*
  190.             ** Write the area to be moved into the data file.
  191.             */
  192.             if( fwrite(&MoveArea, sizeof(struct MESSAGE),
  193.                        1, fpFilename) == NULL )
  194.             {
  195.                 Error( WRITE, __LINE__, Filename );
  196.             }
  197.  
  198.             /*
  199.             ** Create area name string reported to stdout.
  200.             */
  201.             if( MoveArea.NameSize > 0 )
  202.             {
  203.                 strncpy( MoveName, MoveArea.Name, AREALEN );
  204.                 MoveName[MoveArea.NameSize] = '\0';
  205.             }
  206.             else
  207.             {
  208.                 strcpy( MoveName, "[Unused]" );
  209.             }
  210.         
  211.             if( Area.NameSize > 0 )
  212.             {
  213.                 strncpy( InsertName, Area.Name, AREALEN );
  214.                 InsertName[Area.NameSize] = '\0';
  215.             }
  216.             else
  217.             {
  218.                 strcpy( InsertName, "[Unused]" );
  219.             }
  220.  
  221.             printf( "Inserting: %s\n"
  222.                     "   before: %s\n"
  223.                     "\n",
  224.                    MoveName, InsertName );
  225.  
  226.             Moved = TRUE;
  227.         }
  228.  
  229.         /*
  230.         ** Unless this struct is where the area to be moved used to
  231.         ** be, write it to the data file.
  232.         */
  233.         if( CurrentArea != AreaToMove )
  234.         {
  235.             if( fwrite(&Area, sizeof(struct MESSAGE),
  236.                        1, fpFilename) == NULL )
  237.             {
  238.                 Error( WRITE, __LINE__, Filename );
  239.             }
  240.         }
  241.  
  242.         fread(&Area, sizeof(struct MESSAGE), 1, fpBakFile);
  243.     }
  244.  
  245.     fclose( fpBakFile );
  246.     if( ferror(fpBakFile) )
  247.     {
  248.         Error( CLOSE, __LINE__, BakFile );
  249.     }
  250.  
  251.     /*
  252.     ** If the insertion point specified was higher than what existed
  253.     ** in the backup file, the area to be moved will be written to the
  254.     ** end of the data file now.
  255.     */
  256.     if( Moved == FALSE )
  257.     {
  258.         char MoveName[AREALEN + 1]   = "";
  259.  
  260.         if( fwrite(&MoveArea, sizeof(struct MESSAGE),
  261.                    1, fpFilename) == NULL )
  262.         {
  263.             Error( WRITE, __LINE__, Filename );
  264.         }
  265.  
  266.         if( MoveArea.NameSize > 0 )
  267.         {
  268.             strncpy( MoveName, MoveArea.Name, AREALEN );
  269.             MoveName[MoveArea.NameSize] = '\0';
  270.         }
  271.         else
  272.         {
  273.             strcpy( MoveName, "[Unused]" );
  274.         }
  275.  
  276.         printf( "Moved to last area: %s\n"
  277.                 "\n",
  278.                 MoveName );
  279.     }
  280.  
  281.     fclose( fpFilename );
  282.     if( ferror(fpFilename) )
  283.     {
  284.         Error( CLOSE, __LINE__, Filename );
  285.     }
  286.  
  287.     printf( "Successfully re-created %s\n", Filename );
  288.     return( EXIT_SUCCESS );
  289. }
  290.  
  291.  
  292.  
  293. /*********************************************************************
  294. ** FUNCTION: Error
  295. **
  296. ** DESCRIPTION: Error handling and exit function
  297. **
  298. ** PARAMS: int ErrorLevel       errorlevel to exit with
  299. **         int Line             Line number where error occured
  300. **         char * File          Filename where I/O error occured
  301. **
  302. ** RETURN: void
  303. **
  304. ** NOTES: NULL passed to char * File, if error was not file i/o
  305. **        related.
  306. */
  307.  
  308. void
  309. Error( int ErrorLevel, int Line, char * File )
  310. {
  311.     switch( ErrorLevel )
  312.     {
  313.         case HELP:   fprintf( stderr, USAGE );
  314.                      break;
  315.     
  316.         case OPEN:   fprintf( stderr, "ERROR (%d): Cannot open: %s\n",
  317.                              Line, File );
  318.                      break;
  319.     
  320.         case CLOSE:  fprintf( stderr, "ERROR (%d): Cannot close %s\n",
  321.                              Line, File );
  322.                      break;
  323.     
  324.         case READ:   fprintf( stderr, "ERROR (%d): Cannot read %s\n",
  325.                              Line, File );
  326.                      break;
  327.    
  328.         case WRITE:  fprintf( stderr, "ERROR (%d): Cannot write %s\n",
  329.                              Line, File );
  330.                      break;
  331.  
  332.         case SEEK:   fprintf( stderr, "ERROR (%d): Seek error in %s\n",
  333.                               Line, File );
  334.                      break;
  335.  
  336.         case MEMORY: fprintf( stderr, "ERROR (%d): Cannot allocate memory\n",
  337.                              Line );
  338.                      break;
  339.  
  340.         default:     fprintf( stderr, "ERROR (%d): Invalid instruction\n",
  341.                              Line );
  342.     }
  343.     exit( ErrorLevel );
  344. }
  345.