//
// $Header: D:/ext2-os2/RCS/files.c,v 1.14 1995/08/16 17:37:02 Willm Exp Willm $
//
// Linux ext2 file system driver for OS/2 2.x and WARP - Allows OS/2 to
// access your Linux ext2fs partitions as normal drive letters.
// OS/2 implementation : Copyright (C) 1995 Matthieu WILLM
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#define INCL_DOS
#define INCL_DOSERRORS
#include <os2.h> // From the "Developer Connection Device Driver Kit" version 2.0
#include <fsh.h>
#include <os2/types.h>
#include <os2/errors.h>
#include <linux/fs.h>
#include <linux/fs_proto.h>
#include <linux/e2_proto.h>
#include <os2/os2proto.h>
#include <os2/log.h> /* Prototypes des fonctions de log.c */
#include <os2/files.h> /* Prototypes des fonctions de files.c */
//
// These routines will be eventually rewritten and splitted between ext2/namei.c
// (namei()), vfs/namei.c (dir_namei, open_namei, ....) and vfs/open.c (do_open ...)
//
pfile _open_by_inode(struct super_block * p_volume, UINT32 ino_no, UINT32 openmode)
{
pfile p_file;
int rc;
blk_t nblks;
blk_t addr_per_block = p_volume->block_size / sizeof(blk_t);
#ifdef FS_TRACE
kernel_printf("open_by_inode( %lu )", ino_no);
#endif
/*******************************************************************/
/*** Allocates a file descriptor ***/
/*******************************************************************/
if ((p_file = alloc_hfile(p_volume)) == 0) {
fs_err(FUNC_OPEN_BY_INODE, FUNC_ALLOC_HFILE, 0, FILE_FILES_C, __LINE__);
return 0;
}
/*******************************************************************/
/*******************************************************************/
/*** Gets the v-inode (if already exists) or allocates a new one ***/
/*******************************************************************/
if ((p_file->f_inode = iget(p_volume, ino_no)) == NULL) {
fs_err(FUNC_OPEN_BY_INODE, FUNC_GET_VINODE, rc, FILE_FILES_C, __LINE__);
free_hfile(p_volume, p_file);
return 0;
}
/*******************************************************************/
nblks = p_file->f_inode->i_blocks;
/*** out of range ***/
if (nblks > EXT2_NDIR_BLOCKS + addr_per_block +
addr_per_block * addr_per_block +
addr_per_block * addr_per_block * addr_per_block) {
kernel_printf("open_by_inode() : block %lu out of range", nblks);
iput(p_file->f_inode);
free_hfile(p_volume, p_file);
return 0;
}
p_file->f_pos = 0;
p_file->f_mode = openmode;
p_file->index_dir = 0;
p_file->hVPB = p_volume->s_dev;
if (p_file->f_inode->i_op)
p_file->f_op = p_file->f_inode->i_op->default_file_ops;
return p_file;
}
int _close(struct super_block * p_volume, pfile _FS_PTR pp_file)
{
pfile p_file;
int rc;
#ifdef FS_TRACE
kernel_printf("close( %lu )", (*pp_file)->f_inode->i_ino);
#endif
p_file = *pp_file;
iput(p_file->f_inode);
/*****************************************************************************/
/*** Libération du file descriptor ***/
/*****************************************************************************/
if ((rc = free_hfile(p_volume, p_file)) != NO_ERROR) {
fs_err(FUNC_CLOSE, FUNC_FREE_HFILE, rc, FILE_FILES_C, __LINE__); /*** panic ***/
return rc;
}
/*****************************************************************************/
return NO_ERROR;
}
pfile _open_by_name(struct super_block * p_volume, pchar pName, UINT32 openmode)
{
pchar pNom;
pchar pTmp, pTmpUpper1, pTmpUpper2;
pfile p_file;
int ok;
int Fin;
int FinPath;
UINT32 ino_no;
struct dirent Dir;
int rc;
#ifdef FS_TRACE
kernel_printf("open_by_name( %s )", pName);
#endif
/*******************************************************************/
/*** Allocation d'un buffer de travail ***/
/*******************************************************************/
if ((pNom = G_malloc(3 * CCHMAXPATH)) == 0) {
fs_err(FUNC_OPEN_BY_NAME, FUNC_G_malloc, rc, FILE_FILES_C, __LINE__);
return 0;
} /* end if */
memset(pNom, '\0', CCHMAXPATH);
pTmpUpper1 = pNom + CCHMAXPATH;
pTmpUpper2 = pTmpUpper1 + CCHMAXPATH;
/*******************************************************************/
pTmp = DecoupePath(pName, pNom);
/*******************************************************************/
/*** Si c'est le root, on retourne tout de suite ***/
/*******************************************************************/
if (pTmp == 0) {
/*******************************************************************/
/*** Libération du buffer de travail ***/
/*******************************************************************/
if ((rc = G_free(pNom)) != NO_ERROR) {
fs_err(FUNC_OPEN_BY_NAME, FUNC_G_free, rc, FILE_FILES_C, __LINE__);
return 0;
} /* end if */
/*******************************************************************/
return _open_by_inode(p_volume, EXT2_ROOT_INO, openmode);
} /* end if */
/*******************************************************************/
/*******************************************************************/
/*** On boucle sur les composants du path ***/
/*******************************************************************/
ino_no = EXT2_ROOT_INO;
FinPath = 0;
while (FinPath == 0) {
/*******************************************************************/
/*** Ouverture du fichier "." du répertoire ***/
/*******************************************************************/
if ((p_file = _open_by_inode(p_volume, ino_no, OPENMODE_READONLY)) == 0) {
fs_err(FUNC_OPEN_BY_NAME, FUNC_OPEN_BY_INODE, 0, FILE_FILES_C, __LINE__);
if ((rc = G_free(pNom)) != NO_ERROR) {
fs_err(FUNC_OPEN_BY_NAME, FUNC_G_free, rc, FILE_FILES_C, __LINE__);
return 0;
} /* end if */
return 0;
} /* end if */
/*******************************************************************/
ok = 0;
Fin = 0;
/*** recherche du composant dans le fichier "." du composant père ***/
while (Fin == 0) {
if (VFS_readdir(p_file, &Dir) != 0) {
Fin = 1;
} else {
#if 1
if (openmode & OPENMODE_DOSBOX) {
FSH_UPPERCASE(pNom, CCHMAXPATH, pTmpUpper1);
FSH_UPPERCASE(Dir.d_name, CCHMAXPATH, pTmpUpper2);
} else {
strcpy(pTmpUpper1, pNom);
strcpy(pTmpUpper2, Dir.d_name);
}
if (strcmp(pTmpUpper1, pTmpUpper2) == 0) {
#else
if (strcmp(pNom, Dir.d_name) == 0) {
#endif
Fin = 1;
ok = 1;
} /* end if */
} /* end if */
} /* end while */
/*** si pas trouvé on retourne 0 ***/
if (ok == 0) {
if ((rc = _close(p_volume, &p_file)) != NO_ERROR) {
fs_err(FUNC_OPEN_BY_NAME, FUNC_CLOSE, rc, FILE_FILES_C, __LINE__);
return 0; /*** FSH_INTERR() ***/
} /* end if */
if ((rc = G_free(pNom)) != NO_ERROR) {
fs_err(FUNC_OPEN_BY_NAME, FUNC_G_free, rc, FILE_FILES_C, __LINE__);
return 0;
} /* end if */
// kernel_printf("open_by_name() ok = 0 - pTmp = %s - pName = %s - pNom = %s", pTmp, pName, pNom);
return 0;
} /* end if */
/*** sinon on passe au répertoire suivant ***/
ino_no = Dir.d_ino;
if ((rc = _close(p_volume, &p_file)) != NO_ERROR) {
fs_err(FUNC_OPEN_BY_NAME, FUNC_CLOSE, rc, FILE_FILES_C, __LINE__);
return 0; /*** FSH_INTERR() ***/
} /* end if */
if ((pTmp = DecoupePath(pTmp, pNom)) == 0) {
FinPath = 1;
} /* end if */
} /* end while */
/*******************************************************************/
/*******************************************************************/
/*** Libération du buffer de travail ***/
/*******************************************************************/
if ((rc = G_free(pNom)) != NO_ERROR) {
fs_err(FUNC_OPEN_BY_NAME, FUNC_G_free, rc, FILE_FILES_C, __LINE__);
return 0;
} /* end if */
/*******************************************************************/
return _open_by_inode(p_volume, ino_no, openmode);
}