/*
* Motif
*
* Copyright (c) 1987-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these librararies and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/*
* HISTORY
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifdef REV_INFO
#ifndef lint
static char rcsid[] = "$XConsortium: MrmIfile.c /main/13 1996/11/13 13:56:30 drk $"
#endif
#endif
/* (c) Copyright 1989, 1990, DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. */
/*
*++
* FACILITY:
*
* UIL Resource Manager (URM)
*
* ABSTRACT:
*
* This module contains the low-level file utilities
*
*--
*/
/*
*
* INCLUDE FILES
*
*/
#include <Mrm/MrmAppl.h>
#include <Mrm/Mrm.h>
#include <Mrm/IDB.h>
#include <stdio.h> /* Standard IO definitions */
#include <errno.h>
#include <fcntl.h>
#ifndef X_NOT_STDC_ENV
#include <unistd.h>
#endif
/*
*
* DEFINE and MACRO DEFINITIONS
*
*/
#define PMODE 0666 /* Default protection mode before umask */
#define FAILURE -1 /* creat/stat returns this */
/*
*++
*
* PROCEDURE DESCRIPTION:
*
* This routine will take the file name specified and
* open or create it depending on the access parameter.
* An attempt is made to save any existing file of the
* same name.
*
*
* FORMAL PARAMETERS:
*
* name the system-dependent file spec of the IDB file
* to be opened.
* accss access type desired, read or write access.
* os_ext an operating specific structure to take advantage
* of file system features (if any).
* file_id IDB file id used in all calls to low level routines.
* returned_fname The resultant file name.
*
* IMPLICIT INPUTS:
*
* NONE
*
* IMPLICIT OUTPUTS:
*
* NONE
*
* FUNCTION VALUE:
*
* Returns an integer:
*
* MrmSUCCESS - When access is read and open works
* MrmCREATE_NEW - When access is write and open works
* MrmNOT_FOUND - When access is read and the file isn't present
* MrmFAILURE - When the open fails for any other reason
*
* SIDE EFFECTS:
*
* Opens or creates the named file and assigns a channel to it.
*
*--
*/
Cardinal
Idb__FU_OpenFile (char *name,
MrmCode access,
MrmOsOpenParamPtr os_ext,
IDBLowLevelFilePtr *file_id,
char *returned_fname)
{
/*
* Local variables
*/
int file_desc; /* 'unix' file descriptor */
int length; /* the length of the above string */
IDBLowLevelFile *a_file; /* pointer to the file_id */
/* Fill in the result name with the name specified so far */
length = strlen (name);
strcpy (returned_fname, name);
returned_fname[length] = 0;
/* Check if this file is to be opened for read or write access */
if (access == URMWriteAccess)
{
file_desc = open (name, O_RDWR, PMODE);
if (file_desc != FAILURE) /* filename already exists. */
{
if (os_ext == 0)
return MrmFAILURE;
else if (!os_ext->nam_flg.clobber_flg)
return MrmEXISTS; /* no clobber. return Exists */
else if (os_ext->version != MrmOsOpenParamVersion)
return MrmFAILURE;
(void) close (file_desc); /* we care not what close returns*/
}
file_desc = creat (name,PMODE);
if (file_desc == FAILURE) /* verify that worked */
return MrmFAILURE;
close (file_desc); /* we care not what close returns */
file_desc = open (name, O_RDWR, PMODE);
if (file_desc == FAILURE) /* verify that worked */
return MrmFAILURE;
}
/* Else this file is to opened for read access */
else if (access == URMReadAccess)
{
file_desc = open (name, O_RDONLY, PMODE);
/* verify that worked */
if (file_desc == FAILURE)
{
if ( errno == EACCES )
return MrmFAILURE;
else
return MrmNOT_FOUND;
}
}
/* Not URMReadAccess or URMWriteAccess, so return invalid access type */
else
return MrmFAILURE;
/*
* now all we have to do is set up the IDBFile and return the
* proper success code.
*/
*file_id = (IDBLowLevelFilePtr)
XtMalloc(sizeof (IDBLowLevelFile));
if (*file_id==0)
return MrmFAILURE;
a_file = (IDBLowLevelFile *) *file_id;
a_file->name = XtMalloc (length+1);
if (a_file->name==0)
{
XtFree ((char*)*file_id);
return (MrmFAILURE);
}
a_file->file_desc = file_desc;
strcpy (a_file->name, name);
a_file->name[length] = 0;
if (access == URMWriteAccess)
return (MrmCREATE_NEW);
else
return (MrmSUCCESS);
}
/*
*++
*
* PROCEDURE DESCRIPTION:
*
* This routine will close the file and free any allocated storage
*
*
* FORMAL PARAMETERS:
*
* file_id IDB file id
* delete delete the file if == true
*
* IMPLICIT INPUTS:
*
* the file name and channel from the IDBFile record
*
* IMPLICIT OUTPUTS:
*
* NONE
*
* FUNCTION VALUE:
*
* MrmSUCCESS - When the file is closed [and deleted] successfully
* MrmFAILURE - When the close fails
*
* SIDE EFFECTS:
*
* Closes the file, deassigns the channel and possible deletes the file.
*
*--
*/
Cardinal
Idb__FU_CloseFile (IDBLowLevelFile *file_id ,
int delete)
{
/*
* Local variables
*/
int status; /* ret status for sys services */
status = close (file_id->file_desc);
if (status != 0)
return MrmFAILURE;
if (delete) {
status = unlink (file_id->name);
}
XtFree (file_id->name);
XtFree ((char*)file_id);
return MrmSUCCESS;
}
/*
*++
*
* PROCEDURE DESCRIPTION:
*
* This function reads in the desired record into the given
* buffer.
*
* FORMAL PARAMETERS:
*
* file_id the IDB file identifier
* block_num the record number to retrieve
* buffer pointer to the buffer to fill in
*
* IMPLICIT INPUTS:
*
* NONE
*
* IMPLICIT OUTPUTS:
*
* NONE
*
* FUNCTION VALUE:
*
* MrmSUCCESS operation succeeded
* MrmNOT_FOUND entry not found
* MrmFAILURE operation failed, no further reason
*
* SIDE EFFECTS:
*
* The buffer is filled in. Should the $READ fail the buffer's
* content is not predictable.
*
*--
*/
Cardinal
Idb__FU_GetBlock (IDBLowLevelFile *file_id,
IDBRecordNumber block_num,
char *buffer)
{
/*
* Local variables
*/
int number_read; /* the number of bytes actually read */
int fdesc ; /* file descriptor from lowlevel desc */
fdesc = file_id->file_desc ;
lseek (fdesc, (block_num-1)*IDBRecordSize, 0);
number_read = read (file_id->file_desc, buffer, IDBRecordSize);
if (number_read != IDBRecordSize)
return MrmFAILURE;
else
return MrmSUCCESS;
}
/*
*++
*
* PROCEDURE DESCRIPTION:
*
* This function writes the data in the givin buffer into
* the desired record in the file.
*
* FORMAL PARAMETERS:
*
* file_id the IDB file identifier
* block_num the record number to write
* buffer pointer to the buffer to read from
*
* IMPLICIT INPUTS:
*
* NONE
*
* IMPLICIT OUTPUTS:
*
* NONE
*
* FUNCTION VALUE:
*
* Returns an integer by value:
*
* MrmSUCCESS operation succeeded
* MrmFAILURE operation failed, no further reason
*
* SIDE EFFECTS:
*
* the file is modified.
*
*--
*/
Cardinal
Idb__FU_PutBlock (IDBLowLevelFile *file_id,
IDBRecordNumber block_num,
char *buffer)
{
/*
* Local variables
*/
int number_written; /* the # of bytes acctually written */
int fdesc ; /* file descriptor from lowlevel desc */
fdesc = file_id->file_desc ;
lseek (fdesc, (block_num-1)*IDBRecordSize, 0);
number_written = write (file_id->file_desc, buffer, IDBRecordSize);
if (number_written != IDBRecordSize)
return MrmFAILURE;
else
return MrmSUCCESS;
}