430 lines
10 KiB
C
430 lines
10 KiB
C
/*
|
|
* @DEC_COPYRIGHT@
|
|
*/
|
|
/*
|
|
* HISTORY
|
|
* $Log: sc_file.c,v $
|
|
* Revision 1.1.8.6 1996/12/12 20:54:43 Hans_Graves
|
|
* Fix some NT warnings (when linking statically).
|
|
* [1996/12/12 20:07:58 Hans_Graves]
|
|
*
|
|
* Revision 1.1.8.5 1996/11/04 22:38:38 Hans_Graves
|
|
* Fixed open/closes under NT. File closes weren't always happening.
|
|
* [1996/11/04 22:29:53 Hans_Graves]
|
|
*
|
|
* Revision 1.1.8.4 1996/10/28 17:32:18 Hans_Graves
|
|
* Replace longs with dwords for NT portability.
|
|
* [1996/10/28 16:54:46 Hans_Graves]
|
|
*
|
|
* Revision 1.1.8.3 1996/09/18 23:45:38 Hans_Graves
|
|
* Added ScFileClose() for portability
|
|
* [1996/09/18 21:53:20 Hans_Graves]
|
|
*
|
|
* Revision 1.1.8.2 1996/05/07 19:55:45 Hans_Graves
|
|
* Fix file creation under NT.
|
|
* [1996/05/07 17:11:18 Hans_Graves]
|
|
*
|
|
* Revision 1.1.6.2 1996/04/01 16:23:08 Hans_Graves
|
|
* Added ScFileOpen and ScFileRead/Write functions for portability
|
|
* [1996/04/01 16:11:56 Hans_Graves]
|
|
*
|
|
* Revision 1.1.4.3 1996/02/07 23:23:48 Hans_Graves
|
|
* Added ScFileSeek().
|
|
* [1996/02/07 23:21:55 Hans_Graves]
|
|
*
|
|
* Revision 1.1.4.2 1996/01/02 18:30:51 Bjorn_Engberg
|
|
* Got rid of compiler warnings: Added include files for NT.
|
|
* [1996/01/02 15:25:02 Bjorn_Engberg]
|
|
*
|
|
* Revision 1.1.2.5 1995/09/20 14:59:32 Bjorn_Engberg
|
|
* Port to NT
|
|
* [1995/09/20 14:41:12 Bjorn_Engberg]
|
|
*
|
|
* Revision 1.1.2.4 1995/07/12 19:48:22 Hans_Graves
|
|
* Added H261 recognition to ScFileType().
|
|
* [1995/07/12 19:33:48 Hans_Graves]
|
|
*
|
|
* Revision 1.1.2.3 1995/06/22 21:36:00 Hans_Graves
|
|
* Moved ScGetFileType() from sv_gentoc.c. Added some Audio file types.
|
|
* [1995/06/22 21:33:05 Hans_Graves]
|
|
*
|
|
* Revision 1.1.2.2 1995/05/31 18:07:49 Hans_Graves
|
|
* Inclusion in new SLIB location.
|
|
* [1995/05/31 16:13:00 Hans_Graves]
|
|
*
|
|
* Revision 1.1.2.3 1995/04/07 18:55:36 Hans_Graves
|
|
* Added FileExists()
|
|
* [1995/04/07 18:55:13 Hans_Graves]
|
|
*
|
|
* Revision 1.1.2.2 1995/04/07 18:34:21 Hans_Graves
|
|
* Inclusion in SLIB's Su library
|
|
* [1995/04/07 18:33:26 Hans_Graves]
|
|
*
|
|
* $EndLog$
|
|
*/
|
|
/*****************************************************************************
|
|
** Copyright (c) Digital Equipment Corporation, 1995 **
|
|
** **
|
|
** All Rights Reserved. Unpublished rights reserved under the copyright **
|
|
** laws of the United States. **
|
|
** **
|
|
** The software contained on this media is proprietary to and embodies **
|
|
** the confidential technology of Digital Equipment Corporation. **
|
|
** Possession, use, duplication or dissemination of the software and **
|
|
** media is authorized only pursuant to a valid written license from **
|
|
** Digital Equipment Corporation. **
|
|
** **
|
|
** RESTRICTED RIGHTS LEGEND Use, duplication, or disclosure by the U.S. **
|
|
** Government is subject to restrictions as set forth in Subparagraph **
|
|
** (c)(1)(ii) of DFARS 252.227-7013, or in FAR 52.227-19, as applicable. **
|
|
******************************************************************************/
|
|
|
|
#include <fcntl.h>
|
|
#include <sys/types.h>
|
|
#ifndef WIN32
|
|
#include <sys/mman.h>
|
|
#endif /* WIN32 */
|
|
#include <sys/stat.h>
|
|
#include "SC.h"
|
|
#include "SC_err.h"
|
|
|
|
#ifdef WIN32
|
|
#include <string.h>
|
|
#include <sys/stat.h>
|
|
#include <io.h>
|
|
#include <stdio.h>
|
|
#include <windows.h>
|
|
#endif
|
|
|
|
/*
|
|
** Name: ScFileExists
|
|
** Purpose: Does this file exist?
|
|
**
|
|
*/
|
|
ScBoolean_t ScFileExists(char *filename)
|
|
{
|
|
#ifdef WIN32
|
|
struct _stat stat_buf;
|
|
if (_stat(filename, &stat_buf))
|
|
#else
|
|
struct stat stat_buf;
|
|
if (stat(filename, &stat_buf))
|
|
#endif
|
|
return(FALSE);
|
|
else
|
|
return(TRUE);
|
|
}
|
|
|
|
/*
|
|
** Name: ScFileOpenForReading
|
|
** Purpose: Open a file for reading.
|
|
** Returns: Handle to file.
|
|
** -1 if error
|
|
*/
|
|
int ScFileOpenForReading(char *filename)
|
|
{
|
|
if (!filename)
|
|
return(-1);
|
|
#ifdef WIN32
|
|
return((int)_open(filename, _O_RDONLY|_O_BINARY));
|
|
#else /* OSF */
|
|
return((int)open(filename, O_RDONLY));
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
** Name: ScFileOpenForWriting
|
|
** Purpose: Open a file for writing. Creates it if it doesn't already exist.
|
|
** Returns: Handle to file.
|
|
** -1 if error
|
|
*/
|
|
int ScFileOpenForWriting(char *filename, ScBoolean_t truncate)
|
|
{
|
|
if (!filename)
|
|
return(-1);
|
|
#ifdef WIN32
|
|
if (truncate)
|
|
return((int)_open(filename, _O_WRONLY|_O_CREAT|_O_TRUNC|_O_BINARY,
|
|
_S_IREAD|_S_IWRITE));
|
|
else
|
|
return((int)_open(filename, _O_WRONLY|_O_CREAT|_O_BINARY,
|
|
_S_IREAD|_S_IWRITE));
|
|
#else
|
|
if (truncate)
|
|
return((int)open(filename, O_WRONLY|O_CREAT|O_TRUNC,
|
|
S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH));
|
|
else
|
|
return((int)open(filename, O_WRONLY|O_CREAT,
|
|
S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH));
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
** Name: ScFileSize
|
|
** Purpose: Get the size of a file in bytes
|
|
*/
|
|
ScStatus_t ScFileSize(char *filename, unsigned qword *size)
|
|
{
|
|
#ifdef WIN32
|
|
struct _stat stat_buf;
|
|
#else
|
|
struct stat stat_buf;
|
|
#endif
|
|
|
|
if (!filename || !size)
|
|
return(ScErrorBadArgument);
|
|
#ifdef WIN32
|
|
if (_stat(filename, &stat_buf) < 0)
|
|
#else
|
|
if (stat(filename, &stat_buf) < 0)
|
|
#endif
|
|
{
|
|
*size=0;
|
|
return(ScErrorFile);
|
|
}
|
|
*size=(unsigned qword)stat_buf.st_size;
|
|
return(NoErrors);
|
|
}
|
|
|
|
/*
|
|
** Name: ScFileRead
|
|
** Purpose: Read a number of bytes from a file into a buffer
|
|
** Return: Number of bytes read
|
|
** -1 if EOF
|
|
*/
|
|
dword ScFileRead(int fd, void *buffer, unsigned dword bytes)
|
|
{
|
|
#ifdef __VMS
|
|
return((long)fread(buffer, 1, bytes, fd));
|
|
#elif defined(WIN32)
|
|
return((long)_read(fd, buffer, bytes));
|
|
#else /* UNIX */
|
|
return((long)read(fd, buffer, bytes));
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
** Name: ScFileWrite
|
|
** Purpose: Write a number of bytes from a buffer to a file
|
|
** Return: Number of bytes written
|
|
** 0 if error
|
|
*/
|
|
dword ScFileWrite(int fd, void *buffer, unsigned dword bytes)
|
|
{
|
|
#ifdef __VMS
|
|
return((dword)fwrite(buffer, 1, bytes, fd));
|
|
#elif defined(WIN32)
|
|
return((dword)_write(fd, buffer, bytes));
|
|
#else /* UNIX */
|
|
return((dword)write(fd, buffer, bytes));
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
** Name: ScFileSeek
|
|
** Purpose: Seek to a specific position is a file
|
|
*/
|
|
ScStatus_t ScFileSeek(int fd, qword bytepos)
|
|
{
|
|
#ifdef __VMS
|
|
if (fseek(fd,bytepos,SEEK_SET)<0)
|
|
#elif defined(WIN32)
|
|
if (_lseek(fd,(long)bytepos,SEEK_SET)<0)
|
|
#else
|
|
if (lseek(fd,(long)bytepos,SEEK_SET)<0)
|
|
#endif
|
|
return(ScErrorFile);
|
|
else
|
|
return(NoErrors);
|
|
}
|
|
|
|
/*
|
|
** Name: ScFileClose
|
|
** Purpose: Close an opened file
|
|
*/
|
|
void ScFileClose(int fd)
|
|
{
|
|
if (fd>=0)
|
|
{
|
|
#ifdef WIN32
|
|
_close(fd);
|
|
#else /* UNIX or VMS */
|
|
close(fd);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
/*
|
|
** Name: ScFileMap
|
|
** Purpose: Map an entire file to memory
|
|
** if fd<0 then the filename is opened for reading
|
|
** Returns: buffer = memory pointer to the mapped file
|
|
** size = size of the buffer (file)
|
|
*/
|
|
ScStatus_t ScFileMap(char *filename, int *pfd, u_char **buffer,
|
|
unsigned qword *size)
|
|
{
|
|
#ifdef WIN32
|
|
|
|
/*
|
|
* Mapping of files can be supported on NT,
|
|
* but for now return an error and implement
|
|
* file mapping later - BE.
|
|
*/
|
|
return(ScErrorMapFile);
|
|
|
|
#else /* !WIN32 */
|
|
if (!pfd || !filename || !buffer || !size)
|
|
return(ScErrorBadArgument);
|
|
if (ScFileSize(filename, size)!=NoErrors)
|
|
return(ScErrorFile);
|
|
|
|
if (*pfd<0)
|
|
{
|
|
if ((*pfd = open (filename, O_RDONLY)) < 0)
|
|
return(ScErrorFile);
|
|
}
|
|
|
|
*buffer= (unsigned char *)mmap(0, *size, PROT_READ,
|
|
MAP_FILE | MAP_VARIABLE | MAP_PRIVATE, *pfd, 0);
|
|
if (*buffer==(u_char *)-1L)
|
|
{
|
|
*buffer=NULL;
|
|
*size=0;
|
|
return(ScErrorMapFile);
|
|
}
|
|
|
|
#endif /* !WIN32 */
|
|
return(NoErrors);
|
|
}
|
|
|
|
/*
|
|
** Name: ScFileUnMap
|
|
** Purpose: UnMap a file mapped to memory
|
|
** if fd>=0 then the file is closed
|
|
*/
|
|
ScStatus_t ScFileUnMap(int fd, u_char *buffer, unsigned int size)
|
|
{
|
|
if (!buffer || !size)
|
|
return(ScErrorBadArgument);
|
|
#ifndef WIN32
|
|
if (munmap(buffer, size)<0)
|
|
#endif /* !WIN32 */
|
|
return(ScErrorMapFile);
|
|
if (fd>=0)
|
|
ScFileClose(fd);
|
|
return(NoErrors);
|
|
}
|
|
|
|
/*
|
|
** Name: ScGetFileType
|
|
** Purpose: Find out the type of a multmedia file.
|
|
** Returns: UNKNOWN_FILE, AVI_FILE, JFIF_FILE, QUICKTIME_JPEG_FILE
|
|
** MPEG_VIDEO_FILE, MPEG_AUDIO_FILE, MPEG_SYSTEM_FILE,
|
|
** GSM_FILE
|
|
*/
|
|
int ScGetFileType(char *filename)
|
|
{
|
|
int fd;
|
|
u_char buf[20];
|
|
char *fileext;
|
|
|
|
if ((fd = ScFileOpenForReading(filename)) < 0)
|
|
return(ScErrorDevOpen);
|
|
|
|
ScFileRead(fd, buf, 11);
|
|
|
|
/*
|
|
** MPEG video file
|
|
*/
|
|
if ((buf[0] == 0) &&
|
|
(buf[1] == 0) &&
|
|
(buf[2] == 1) &&
|
|
(buf[3] == 0xb3)) {
|
|
ScFileClose(fd);
|
|
return(MPEG_VIDEO_FILE);
|
|
}
|
|
/*
|
|
** MPEG system file
|
|
*/
|
|
if ((buf[0] == 0x00) &&
|
|
(buf[1] == 0x00) &&
|
|
(buf[2] == 0x01) &&
|
|
(buf[3] == 0xba)) {
|
|
ScFileClose(fd);
|
|
return(MPEG_SYSTEM_FILE);
|
|
}
|
|
/*
|
|
** H261 video stream file
|
|
*/
|
|
if ((buf[0] == 0x00) &&
|
|
(buf[1] == 0x01) &&
|
|
(buf[2] == 0x00) &&
|
|
(buf[3] == 0x88)) {
|
|
ScFileClose(fd);
|
|
return(H261_FILE);
|
|
}
|
|
/*
|
|
** JFIF file (ffd8 = Start-Of-Image marker)
|
|
*/
|
|
if ((buf[0] == 0xff) &&
|
|
(buf[1] == 0xd8)) {
|
|
ScFileClose(fd);
|
|
return(JFIF_FILE);
|
|
}
|
|
/*
|
|
** QUICKTIME JPEG file (4 ignored bytes, "mdat", ff, d8, ff)
|
|
*/
|
|
if ((strncmp(&buf[4], "mdat", 4) == 0 ) &&
|
|
(buf[8] == 0xff) &&
|
|
(buf[9] == 0xd8) &&
|
|
(buf[10] == 0xff)) {
|
|
ScFileClose(fd);
|
|
return(QUICKTIME_JPEG_FILE);
|
|
}
|
|
/******* use the file's extension to help guess the type ********/
|
|
for (fileext=filename; *fileext; fileext++)
|
|
if (*fileext=='.' && *(fileext+1)!='.')
|
|
{
|
|
fileext++;
|
|
if (strncmp(fileext, "p64", 3)==0)
|
|
{
|
|
ScFileClose(fd);
|
|
return(H261_FILE);
|
|
}
|
|
if (strncmp(fileext, "gsm", 3)==0)
|
|
{
|
|
ScFileClose(fd);
|
|
return(GSM_FILE);
|
|
}
|
|
if (strncmp(fileext, "pcm", 3)==0)
|
|
{
|
|
ScFileClose(fd);
|
|
return(PCM_FILE);
|
|
}
|
|
if (strncmp(fileext, "wav", 3)==0 && strncmp(buf, "RIFF", 4)==0)
|
|
{
|
|
ScFileClose(fd);
|
|
return(WAVE_FILE);
|
|
}
|
|
if (strncmp(fileext, "mp", 2)==0 && buf[0]==0xFF)
|
|
{
|
|
ScFileClose(fd);
|
|
return(MPEG_AUDIO_FILE);
|
|
}
|
|
break;
|
|
}
|
|
|
|
/*
|
|
** AVI RIFF file
|
|
*/
|
|
if ( strncmp(buf, "RIFF", 4) == 0 ) {
|
|
ScFileClose(fd);
|
|
return(AVI_FILE);
|
|
}
|
|
|
|
ScFileClose(fd);
|
|
return(UNKNOWN_FILE);
|
|
}
|
|
|