/*   This is a set of 3 general functions that will perform random            *
*    file access.  `ropen()' opens a random file or creats it if it           *
*    doesn't exist.  `hirec()' returns the high or last record in a           *
*    file.  `rfile()' preforms the actual read/write operations.              *
*    YOU MUST `close(port)' A FILE WHEN YOU ARE DONE.                         *
*    EACH RECORD is a STRUCTURE of size `sz', that is `sz=sizeof(*data);'.    *
*    `data' is the pointer to the record structure that has been              *
*    loaded prior to a read, or where data is written into.                   *
*    `rfile()' returns the number of the record acted upon, should be         *
*    the one you called UNLESS you called a record number higher than         *
*    the last record, then the actual record number is returned.              *
*    See the comments in the text for more info.                              *
*/

/*   RFILE.C  Random file access functions  */

#include <io.h>


int ropen(char * filspc);
int rclose(int port);
int rfile(int port, int rec, char * data, int sz, char mode);
int hirec(int port, int sz);

#define O_RDWR   2
#define O_CREAT  0x0100

int ropen(char * filspc)   /*  open file for random access  */
{
    int port;

    port = open( filspc, O_RDWR | O_CREAT );
    return( port );  /*  port<0 = error  */
}


int rclose(int port)   /*  close random access file */
{
    int    stat;

    stat = close( port );
    return( stat );
}


int rfile(int port, int rec, char * data, int sz, char mode)
                                  /*   random file access              *
                                   *   assumes port assigned           *
                                   *  sz = sizeof(structure)           *
                                   *  *data = random record structure  *
                                   *  mode = r => read                 *
                                             w => write                */

{
    int stat, read(), write(), lrec, hirec();
    long pos, lseek();

    stat = 0;
    lrec = hirec( port, sz);
    if( rec>lrec )
    {
       if(mode=='w')
           rec = lrec+1;
       else
           rec = lrec;
    };
    rec -= 1;
    pos = rec * sz;
    lseek( port, pos, 0);
    switch (mode)
    {
       case 'r':
           stat = read( port, data, sz);
           break;
       case 'w':
           stat = write( port, data, sz);
           break;
    };
    if( stat <= 0 )
       return( stat-1 );   /* -1=EOF, <(-1)=error */
    else
       return( rec+1 );
}


int hirec(int port, int sz)   /*  random record count  */
/* sz = sizeof(structure)  */

{
    int ct;
    long ef, lseek();

    ef = lseek( port, 0L, 2);
    ct = ef/sz;
    return( ct );
}