⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 os2rfx.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
字号:
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  OS/2 32-bit local implementation of remote file access.
*
****************************************************************************/


#include <stddef.h>
#include <string.h>
#include <ctype.h>
#define INCL_BASE
#define INCL_DOSDEVICES
#define INCL_DOSMEMMGR
#define INCL_DOSSIGNALS
#include <os2.h>
#include <os2dbg.h>
#include "trpimp.h"

#if 0
typedef struct {
    struct {
        char                i_dunno[13];
        unsigned int        dir_entry_num;
        unsigned int        cluster;
        char                i_still_dunno[4];
    } dos;
    char                attr;
    unsigned int        time;
    unsigned int        date;
    long                size;
    char                name[14];
} dos_dta;
#endif

#define NIL_DOS_HANDLE  ((HFILE)0xFFFF)
#define BUFF_SIZE       256


unsigned ReqRfx_rename( void )
{
    char                *old_name;
    char                *new_name;
    rfx_rename_ret      *ret;

    old_name = GetInPtr( sizeof( rfx_rename_req ) );
    new_name = GetInPtr( sizeof( rfx_rename_req ) + strlen( old_name ) + 1 );
    ret = GetOutPtr( 0 );
    ret->err = DosMove( old_name, new_name );
    return( sizeof( *ret ) );
}


unsigned ReqRfx_mkdir( void )
{
    char                *name;
    rfx_mkdir_ret       *ret;

    name = GetInPtr( sizeof( rfx_mkdir_req ) );
    ret = GetOutPtr( 0 );
    ret->err = DosCreateDir( name, 0 );
    return( sizeof( *ret ) );
}


unsigned ReqRfx_rmdir( void )
{
    char                *name;
    rfx_rmdir_ret       *ret;

    name = GetInPtr( sizeof( rfx_rmdir_req ) );
    ret = GetOutPtr( 0 );
    ret->err = DosDeleteDir( name );
    return( sizeof( *ret ) );
}


unsigned ReqRfx_setdrive( void )
{
    rfx_setdrive_req    *acc;
    rfx_setdrive_ret    *ret;

    acc = GetInPtr( 0 );
    ret = GetOutPtr( 0 );
    ret->err = DosSetDefaultDisk( acc->drive + 1 );
    return( sizeof( *ret ) );
}


unsigned ReqRfx_getdrive( void )
{
    ULONG               drive;
    ULONG               map;
    rfx_getdrive_ret    *ret;

    ret = GetOutPtr( 0 );
    if( DosQueryCurrentDisk( &drive, &map ) == 0 ) {
        ret->drive = drive - 1;
    } else {
        ret->drive = 0;
    }
    return( sizeof( *ret ) );
}


unsigned ReqRfx_setcwd( void )
{
    char                *name;
    rfx_setcwd_ret      *ret;

    name = GetInPtr( sizeof( rfx_setcwd_req ) );
    ret = GetOutPtr( 0 );
    ret->err = DosSetCurrentDir( name );
    return( sizeof( *ret ) );
}


unsigned ReqRfx_getfileattr( void )
{
    FILESTATUS3         info;
    USHORT              ret_code;
    char                *name;
    rfx_getfileattr_ret *ret;

    name = GetInPtr( sizeof( rfx_getfileattr_req ) );
    ret = GetOutPtr( 0 );
    ret_code = DosQueryPathInfo( name, FIL_STANDARD, &info, sizeof( info ) );
    ret->attribute = (ret_code == 0) ? info.attrFile : (0xffff0000 | ret_code);
    return( sizeof( *ret ) );
}


unsigned ReqRfx_setfileattr( void )
{
    FILESTATUS3         info;
    char                *name;
    rfx_setfileattr_req *acc;
    rfx_setfileattr_ret *ret;

    // Not tested, and not used right now
    acc = GetInPtr( 0 );
    name = GetInPtr( sizeof( *acc ) );
    ret = GetOutPtr( 0 );
    ret->err = DosQueryPathInfo( name, FIL_STANDARD, &info, sizeof( info ) );
    if (ret->err == 0) {
        info.attrFile = acc->attribute;
        ret->err = DosSetPathInfo( name, FIL_STANDARD, &info, sizeof( info ), 0 );
        }
    return( sizeof( *ret ) );
}

unsigned ReqRfx_getfreespace( void )
{
    FSALLOCATE              info;
    rfx_getfreespace_req    *acc;
    rfx_getfreespace_ret    *ret;

    acc = GetInPtr( 0 );
    ret = GetOutPtr( 0 );
    DosQueryFSInfo( acc->drive, 1, (PBYTE)&info, sizeof( info ) );
    ret->size = (long)info.cbSector
                 * (long)info.cSectorUnit
                 * (long)info.cUnitAvail;
    return( sizeof( *ret ) );
}

static void mylocaltime( ULONG date_time, USHORT *time, USHORT *date )
{
    unsigned      num_yr_since_1970;
    unsigned      num_leap_since_1970;
    unsigned      sec, min, hour, day, month, year;
    unsigned      day_since_jan[] = { 0,31,59,90,120,151,181,212,243,273,304,334,365 };

    num_yr_since_1970 = date_time / 31622400UL;
    num_leap_since_1970 = (num_yr_since_1970 - 2) / 4;
    date_time -= ((num_leap_since_1970 * 366 +
                  (num_yr_since_1970 - num_leap_since_1970) * 365)
                   * 86400 );
    day = (date_time / 86400) + 1;   // Start from Jan 1, not Jan 0
    if( ((num_yr_since_1970 - 2) % 4) == 0 ) {
        //leap
        if( day >= 366 ) {
            day -= 366;
            num_yr_since_1970++;
        }
    } else {
        if( day >= 365 ) {
            day -= 365;
            num_yr_since_1970++;
        }
    }
    if( (( num_yr_since_1970 - 2) % 4) == 0 ) {
        for( month = 2; month <= 12; ++day_since_jan[month], ++month )
            ;
    }
    year = num_yr_since_1970 - 10;
    for( month = 1; (day > day_since_jan[month] && month <= 12); month++ )
        ;
    day -= day_since_jan[month - 1];
    date_time %= 86400;
    hour = date_time / 3600;
    date_time %= 3600;
    min = date_time / 60;
    sec = date_time % 60;

    *time = (hour << 11) | (min << 5) | (sec / 2);
    *date = (year << 9) | (month << 5) | day;
}

unsigned ReqRfx_setdatetime( void )
{
    FILESTATUS3         info;
    FTIME               time;
    FDATE               date;
    rfx_setdatetime_req *acc;

    acc = GetInPtr( 0 );
    mylocaltime( acc->time, (USHORT*)&time, (USHORT*)&date );
    info.fdateCreation = date;
    info.ftimeCreation = time;
    info.fdateLastAccess = date;
    info.ftimeLastAccess = time;
    info.fdateLastWrite = date;
    info.ftimeLastWrite = time;
    DosSetFileInfo( acc->handle, FIL_STANDARD, &info, sizeof( info ) );
    return( 0 );
}

#define NM_SEC_1970_1980 315532800UL

static unsigned long mymktime( unsigned time, unsigned date )
{
    unsigned      day_since_jan[] = { 0,31,59,90,120,151,181,212,243,273,304,334 };
    unsigned      num_yr_since_1980;
    unsigned      num_leap_since_1980;
    unsigned      sec, min, hour, day, month, year;

    sec   = (time & 0x1f) * 2;
    min   = (time >> 5) & 0x3f;
    hour  = (time >> 11) & 0x1f;
    day   = date & 0x1f;
    month = ((date >> 5) & 0xf);
    year  = ((date >> 9) & 0x7f);

    //note that year 2000 is a leap year and I don't think this prog. will still
    //be around in year 2099....
    num_yr_since_1980 = year;
    num_leap_since_1980 = (num_yr_since_1980 + 3) / 4;
    if( ( (num_yr_since_1980 % 4) == 0 ) && (month > 2) ) {  // is leap year
        day++;
    }
    day += (num_leap_since_1980 * 366
             + (num_yr_since_1980 - num_leap_since_1980) * 365
             + day_since_jan[month - 1] - 1);
    return( NM_SEC_1970_1980 + day*86400 + hour*3600 + min*60 + sec );
}

unsigned ReqRfx_getdatetime( void )
{
    rfx_getdatetime_req *acc;
    rfx_getdatetime_ret *ret;
    FILESTATUS3         info;

    acc = GetInPtr( 0 );
    ret = GetOutPtr( 0 );
    DosQueryFileInfo( acc->handle, FIL_STANDARD, (char *)&info, sizeof( info ) );
    ret->time = mymktime( *(USHORT *)&info.ftimeLastWrite,
                          *(USHORT *)&info.fdateLastWrite );
    return( sizeof( *ret ) );
}

unsigned ReqRfx_getcwd( void )
{
    ULONG               len = BUFF_SIZE;
    rfx_getcwd_req      *acc;
    rfx_getcwd_ret      *ret;
    char                *buff;

    acc = GetInPtr( 0 );
    ret = GetOutPtr( 0 );
    buff = GetOutPtr( sizeof( *ret ) );
    ret->err = DosQueryCurrentDir( acc->drive, buff, &len );
    return( sizeof( *ret ) + len );
}

static void MoveDirInfo( FILEFINDBUF3 *os2, trap_dta *dos )
{
    dos->dos.dir_entry_num = *(USHORT *)&os2->fdateLastWrite;
    dos->dos.cluster = *(USHORT *)&os2->ftimeLastWrite;
    dos->attr = os2->attrFile;
    dos->time = *(USHORT *)&os2->ftimeLastWrite;
    dos->date = *(USHORT *)&os2->fdateLastWrite;
    dos->size = os2->cbFile;
    strcpy( dos->name, os2->achName );
}

unsigned ReqRfx_findfirst( void )
{
    FILEFINDBUF3         info;
    APIRET               rc;
    HDIR                 hdl = 1;
    ULONG                count = 1;
    rfx_findfirst_req    *acc;
    rfx_findfirst_ret    *ret;
    char                 *filename;

    acc = GetInPtr( 0 );
    filename = GetInPtr( sizeof( *acc ) );
    ret = GetOutPtr( 0 );
    rc = DosFindFirst( filename, &hdl, acc->attrib, &info,
                      sizeof( info ), &count, FIL_STANDARD );
    if( rc == 0 ) {
        MoveDirInfo( &info, (trap_dta *)GetOutPtr( sizeof( *ret ) ) );
        ret->err = 0;
        return( sizeof( *ret ) + sizeof( trap_dta ) );
    } else {
        ret->err = rc;
        return( sizeof( *ret ) );
    }
}

unsigned ReqRfx_findnext( void )
{
    FILEFINDBUF3        info;
    APIRET              rc;
    ULONG               count = 1;
    rfx_findnext_ret    *ret;

    ret = GetOutPtr( 0 );
    rc = DosFindNext( 1, &info, sizeof( info ), &count );
    if( rc == 0 ) {
        MoveDirInfo( &info, (trap_dta *)GetOutPtr( sizeof( *ret ) ) );
        ret->err = 0;
        return( sizeof( *ret ) + sizeof( trap_dta ) );
    } else {
        ret->err = rc;
        return( sizeof( *ret ) );
    }
}

unsigned ReqRfx_findclose( void )
{
    return( 0 );
}

unsigned ReqRfx_nametocannonical( void )
{
    rfx_nametocannonical_ret    *ret;
    char                        *name;
    char                        *fullname;
    char                        *p;
    int                         level = 0;
    ULONG                       drive;
    ULONG                       map;
    ULONG                       len = BUFF_SIZE;

    // Not tested, and not used right now
    name = GetInPtr( sizeof( rfx_nametocannonical_req ) );
    ret = GetOutPtr( 0 );
    fullname = GetOutPtr( sizeof( *ret ) );
    ret->err = 1;
    while( *name == ' ' ) {
        name++;
    }
    if( *(name + 1) == ':' ) {
        drive = toupper( *name ) - 'A';
        name += 2;
    } else {
        DosQueryCurrentDisk( &drive, &map );
    }
    if( *name != '\\' ) {
        *fullname++ = '\\';
        // DOS : TinyGetCWDir( fullname, TinyGetCurrDrive() + 1 );
        DosQueryCurrentDir( drive + 1, fullname, &len );
        if( *fullname != '\0' ) {
            level++;
            while( *fullname != '\0' ) {
                if( *fullname == '\\' ) {
                    level++;
                }
                fullname++;
            }
        }
    } else {
        name++;
        if( *name == '\0' ) {
            *fullname++ = '\\';
        }
        *fullname = '\0';
    }
    p = name;
    for( ;; ) {
        for( ;; ) {
            if( *p == '\0' )
                goto done;
            if( *p == '\\' )
                break;
            if( *p == '/' )
                break;
            ++p;
        }
        if( strcmp( p, "." ) == 0 ) {
        } else if( strcmp( p, ".." ) == 0 ) {
            if( level > 0 ) {
                while( *fullname != '\\' ) {
                    fullname--;
                }
                level--;
                *fullname = '\0';
            } else {
                ret->err = 1;
                break;
            }
        } else {
            *fullname++ = '\\';
            level++;
            do {
                *fullname++ = *p++;
            } while( *p != '\0' )
                ;
            *fullname = '\0';
        }
    }
done:
    return( sizeof( *ret ) + strlen( GetOutPtr( sizeof( *ret ) ) ) + 1 );
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -