Metropoli BBS
VIEWER: files.c MODE: TEXT (CP437)
//
// $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);
}


[ RETURN TO DIRECTORY ]