Annotation of uae/src/od-win32/posixemu.c, revision 1.1.1.4

1.1       root        1: /* 
                      2:  * UAE - The Un*x Amiga Emulator
                      3:  *
                      4:  * Win32 interface
                      5:  *
                      6:  * Copyright 1997 Mathias Ortmann
                      7:  */
                      8: 
1.1.1.2   root        9: #include "sysconfig.h"
                     10: #include "sysdeps.h"
                     11: 
1.1       root       12: #include <windows.h>
                     13: #include <stdlib.h>
                     14: #include <stdarg.h>
1.1.1.3   root       15: #include <ddraw.h>
1.1       root       16: #include <commctrl.h>
                     17: #include <commdlg.h>
                     18: #include <stdio.h>
                     19: #include <fcntl.h>
                     20: #include <sys/stat.h>
                     21: #include <io.h>
1.1.1.3   root       22: #include <sys/types.h>
                     23: #include <sys/timeb.h>
                     24: #include <process.h>
1.1       root       25: #include "options.h"
1.1.1.3   root       26: #include "posixemu.h"
                     27: #include "filesys.h"
                     28: 
                     29: /* Our Win32 implementation of this function */
                     30: void gettimeofday( struct timeval *tv, void *blah )
                     31: {
                     32:     struct timeb time;
                     33:     ftime( &time );
                     34: 
                     35:     tv->tv_sec = time.time;
                     36:     tv->tv_usec = time.millitm * 1000;
                     37: }
                     38: 
                     39: /* convert time_t to/from AmigaDOS time */
                     40: #define secs_per_day ( 24 * 60 * 60 )
                     41: #define diff ( (8 * 365 + 2) * secs_per_day )
                     42: 
                     43: void get_time(time_t t, long* days, long* mins, long* ticks)
                     44: {
                     45:     /* time_t is secs since 1-1-1970 */
                     46:     /* days since 1-1-1978 */
                     47:     /* mins since midnight */
                     48:     /* ticks past minute @ 50Hz */
                     49: 
                     50:     t -= diff;
                     51:     *days = t / secs_per_day;
                     52:     t -= *days * secs_per_day;
                     53:     *mins = t / 60;
                     54:     t -= *mins * 60;
                     55:     *ticks = t * 50;
                     56: }
1.1       root       57: 
                     58: /* stdioemu, posixemu, mallocemu, and various file system helper routines */
                     59: static DWORD lasterror;
                     60: 
                     61: static int isillegal (unsigned char *str)
                     62: {
1.1.1.3   root       63:     int result = 0;
1.1       root       64:     unsigned char a = *str, b = str[1], c = str[2];
                     65: 
                     66:     if (a >= 'a' && a <= 'z')
                     67:        a &= ~' ';
                     68:     if (b >= 'a' && b <= 'z')
                     69:        b &= ~' ';
                     70:     if (c >= 'a' && c <= 'z')
                     71:        c &= ~' ';
                     72: 
1.1.1.3   root       73:     result = ( (a == 'A' && b == 'U' && c == 'X') ||
1.1.1.4 ! root       74:                (a == 'C' && b == 'O' && c == 'N') ||
        !            75:                (a == 'P' && b == 'R' && c == 'N') ||
        !            76:                (a == 'N' && b == 'U' && c == 'L') );
1.1.1.3   root       77: 
                     78:     return result;
1.1       root       79: }
                     80: 
                     81: static int checkspace (char *str, char s, char d)
                     82: {
                     83:     char *ptr = str;
                     84: 
                     85:     while (*ptr && *ptr == s)
                     86:        ptr++;
                     87: 
                     88:     if (!*ptr || *ptr == '/' || *ptr == '\\') {
                     89:        while (str < ptr)
                     90:            *(str++) = d;
                     91:        return 0;
                     92:     }
                     93:     return 1;
                     94: }
                     95: 
                     96: /* This is sick and incomplete... in the meantime, I have discovered six new illegal file name formats
                     97:  * M$ sucks! */
1.1.1.2   root       98: void fname_atow (const char *src, char *dst, int size)
1.1       root       99: {
1.1.1.2   root      100:     char *lastslash = dst, *strt = dst, *posn = NULL, *temp = NULL;
1.1       root      101:     int i, j;
                    102: 
1.1.1.2   root      103:     temp = xmalloc( size );
                    104: 
1.1       root      105:     while (size-- > 0) {
                    106:        if (!(*dst = *src++))
                    107:            break;
                    108: 
                    109:        if (*dst == '~' || *dst == '|' || *dst == '*' || *dst == '?') {
                    110:            if (size > 2) {
                    111:                sprintf (dst, "~%02x", *dst);
                    112:                size -= 2;
                    113:                dst += 2;
                    114:            }
                    115:        } else if (*dst == '/') {
1.1.1.3   root      116:            if (checkspace (lastslash, ' ', (char)0xa0) && (dst - lastslash == 3 || (dst - lastslash > 3 && lastslash[3] == '.')) && isillegal (lastslash)) {
1.1       root      117:                i = dst - lastslash - 3;
                    118:                dst++;
                    119:                for (j = i + 1; j--; dst--)
                    120:                    *dst = dst[-1];
1.1.1.3   root      121:                *(dst++) = (char)0xa0;
1.1       root      122:                dst += i;
                    123:                size--;
1.1.1.3   root      124:            } else if (*lastslash == '.' && (dst - lastslash == 1 || (lastslash[1] == '.' && dst - lastslash == 2)) && size) {
                    125:                *(dst++) = (char)0xa0;
1.1       root      126:                size--;
                    127:            }
                    128:            *dst = '\\';
                    129:            lastslash = dst + 1;
                    130:        }
                    131:        dst++;
                    132:     }
                    133: 
1.1.1.3   root      134:     if (checkspace (lastslash, ' ', (char)0xa0) && (dst - lastslash == 3 || (dst - lastslash > 3 && lastslash[3] == '.')) && isillegal (lastslash) && size > 1) {
1.1       root      135:        i = dst - lastslash - 3;
                    136:        dst++;
                    137:        for (j = i + 1; j--; dst--)
                    138:            *dst = dst[-1];
1.1.1.3   root      139:        *(dst++) = (char)0xa0;
1.1       root      140:     } else if (!strcmp (lastslash, ".") || !strcmp (lastslash, ".."))
                    141:        strcat (lastslash, "\xa0");
                    142: 
1.1.1.2   root      143:     /* Major kludge, because I can't find the problem... */
                    144:     if( ( posn = strstr( strt, "..\xA0\\" ) ) == strt && temp)
1.1       root      145:     {
1.1.1.4 ! root      146:        strcpy( temp, "..\\" );
        !           147:        strcat( temp, strt + 4 );
        !           148:        strcpy( strt, temp );
1.1       root      149:     }
1.1.1.3   root      150: 
                    151:     /* Another major kludge, for the MUI installation... */
                    152:     if( *strt == ' ' ) /* first char as a space is illegal in Windoze */
                    153:     {
1.1.1.4 ! root      154:        sprintf( temp, "~%02x%s", ' ', strt+1 );
        !           155:        strcpy( strt, temp );
1.1.1.3   root      156:     }
1.1       root      157: }
                    158: 
                    159: static int hextol (char a)
                    160: {
                    161:     if (a >= '0' && a <= '9')
                    162:        return a - '0';
                    163:     if (a >= 'a' && a <= 'f')
                    164:        return a - 'a' + 10;
                    165:     if (a >= 'A' && a <= 'F')
                    166:        return a - 'A' + 10;
                    167:     return 2;
                    168: }
                    169: 
                    170: /* Win32 file name restrictions suck... */
                    171: void fname_wtoa (unsigned char *ptr)
                    172: {
                    173:     unsigned char *lastslash = ptr;
                    174: 
                    175:     while (*ptr) {
                    176:        if (*ptr == '~') {
                    177:            *ptr = hextol (ptr[1]) * 16 + hextol (ptr[2]);
                    178:            strcpy (ptr + 1, ptr + 3);
                    179:        } else if (*ptr == '\\') {
1.1.1.3   root      180:            if (checkspace (lastslash, ' ', (char)0xa0) && ptr - lastslash > 3 && lastslash[3] == 0xa0 && isillegal (lastslash)) {
1.1       root      181:                ptr--;
                    182:                strcpy (lastslash + 3, lastslash + 4);
                    183:            }
                    184:            *ptr = '/';
                    185:            lastslash = ptr + 1;
                    186:        }
                    187:        ptr++;
                    188:     }
                    189: 
1.1.1.3   root      190:     if (checkspace (lastslash, ' ', (char)0xa0) && ptr - lastslash > 3 && lastslash[3] == 0xa0 && isillegal (lastslash))
1.1       root      191:        strcpy (lastslash + 3, lastslash + 4);
                    192: }
                    193: 
1.1.1.3   root      194: #ifndef HAVE_TRUNCATE
                    195: int truncate (const char *name, long int len)
1.1       root      196: {
1.1.1.3   root      197:     HANDLE hFile;
                    198:     BOOL bResult = FALSE;
                    199:     int result = -1;
                    200: 
                    201: #if 0
                    202:     char buf[1024];
                    203: 
                    204:     fname_atow(name,buf,sizeof buf);
                    205: 
                    206:     if( ( hFile = CreateFile( buf, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1.1.1.4 ! root      207:                              OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ) ) != INVALID_HANDLE_VALUE )
1.1.1.3   root      208:     {
1.1.1.4 ! root      209:        if( SetFilePointer( hFile, len, NULL, FILE_BEGIN ) == (DWORD)len )
        !           210:        {
        !           211:            if( SetEndOfFile( hFile ) == TRUE )
        !           212:                result = 0;
        !           213:        }
        !           214:        else
        !           215:        {
        !           216:            write_log( "SetFilePointer() failure for %s to posn %d\n", buf, len );
        !           217:        }
        !           218:        CloseHandle( hFile );
1.1.1.3   root      219:     }
                    220:     else
                    221:     {
1.1.1.4 ! root      222:        write_log( "CreateFile() failed to open %s\n", buf );
1.1.1.3   root      223:     }
                    224: #else
                    225:     if( ( hFile = CreateFile( name, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1.1.1.4 ! root      226:                              OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ) ) != INVALID_HANDLE_VALUE )
1.1.1.3   root      227:     {
1.1.1.4 ! root      228:        if( SetFilePointer( hFile, len, NULL, FILE_BEGIN ) == (DWORD)len )
        !           229:        {
        !           230:            if( SetEndOfFile( hFile ) == TRUE )
        !           231:                result = 0;
        !           232:        }
        !           233:        else
        !           234:        {
        !           235:            write_log( "SetFilePointer() failure for %s to posn %d\n", name, len );
        !           236:        }
        !           237:        CloseHandle( hFile );
1.1.1.3   root      238:     }
                    239:     else
                    240:     {
1.1.1.4 ! root      241:        write_log( "CreateFile() failed to open %s\n", name );
1.1.1.3   root      242:     }
                    243: #endif
                    244:     if( result == -1 )
1.1.1.4 ! root      245:        lasterror = GetLastError();
1.1.1.3   root      246:     return result;
1.1       root      247: }
1.1.1.3   root      248: #endif
1.1       root      249: 
1.1.1.3   root      250: #if 0
                    251: 
                    252: DIR {
                    253:     WIN32_FIND_DATA finddata;
                    254:     HANDLE hDir;
                    255:     int getnext;
                    256: };
                    257: 
                    258: DIR *posixemu_opendir(const char *path)
1.1       root      259: {
1.1.1.3   root      260:     char buf[1024];
                    261:     DIR *dir;
                    262: 
                    263:     if (!(dir = (DIR *)GlobalAlloc(GPTR,sizeof(DIR))))
                    264:     {
                    265:            lasterror = GetLastError();
                    266:            return 0;
                    267:     }
                    268: #if 0
                    269:     fname_atow(path,buf,sizeof buf-4);
                    270: #else
                    271:     strcpy( buf, path );
                    272: #endif
                    273:     strcat(buf,"\\*");
                    274: 
                    275:     if ((dir->hDir = FindFirstFile(buf,&dir->finddata)) == INVALID_HANDLE_VALUE)
                    276:     {
                    277:            lasterror = GetLastError();
                    278:            GlobalFree(dir);
                    279:            return 0;
                    280:     }
                    281: 
                    282:     return dir;
1.1       root      283: }
                    284: 
1.1.1.3   root      285: struct dirent *posixemu_readdir(DIR *dir)
1.1       root      286: {
1.1.1.3   root      287:     if (dir->getnext)
                    288:     {
                    289:        if (!FindNextFile(dir->hDir,&dir->finddata))
                    290:        {
                    291:            lasterror = GetLastError();
                    292:            return 0;
                    293:        }
                    294:     }
                    295:     dir->getnext = TRUE;
                    296: 
                    297:     fname_wtoa(dir->finddata.cFileName);
                    298:     return (struct dirent *)dir->finddata.cFileName;
1.1       root      299: }
                    300: 
1.1.1.3   root      301: void posixemu_closedir(DIR *dir)
1.1       root      302: {
1.1.1.3   root      303:     FindClose(dir->hDir);
                    304:     GlobalFree(dir);
1.1       root      305: }
                    306: #endif
1.1.1.3   root      307: 
                    308: int w32fopendel(char *name, char *mode, int delflag)
1.1       root      309: {
1.1.1.3   root      310:        HANDLE hFile;
                    311: 
                    312:        if ((hFile = CreateFile(name,
                    313:                mode[1] == '+' ? GENERIC_READ | GENERIC_WRITE : GENERIC_READ,   // ouch :)
                    314:                FILE_SHARE_READ | FILE_SHARE_WRITE,
                    315:                NULL,
                    316:                OPEN_EXISTING,
                    317:                delflag ? FILE_ATTRIBUTE_NORMAL|FILE_FLAG_DELETE_ON_CLOSE : FILE_ATTRIBUTE_NORMAL,
                    318:                NULL)) == INVALID_HANDLE_VALUE)
                    319:        {
                    320:                lasterror = GetLastError();
                    321:                hFile = 0;
                    322:        }
                    323: 
                    324:        return (int)hFile;                      /* return handle */
1.1       root      325: }
1.1.1.3   root      326:        
                    327: DWORD getattr(const char *name, LPFILETIME lpft, size_t *size)
                    328: {
                    329:        HANDLE hFind;
                    330:        WIN32_FIND_DATA fd;
1.1       root      331: 
1.1.1.3   root      332:        if ((hFind = FindFirstFile(name,&fd)) == INVALID_HANDLE_VALUE)
                    333:        {
                    334:                lasterror = GetLastError();
                    335: 
                    336:                fd.dwFileAttributes = GetFileAttributes(name);
                    337: 
                    338:                return fd.dwFileAttributes;
                    339:        }
                    340: 
                    341:        FindClose(hFind);
                    342: 
                    343:        if (lpft) *lpft = fd.ftLastWriteTime;
                    344:        if (size) *size = fd.nFileSizeLow;
                    345: 
                    346:        return fd.dwFileAttributes;
                    347: }
                    348: 
                    349: #if 0
                    350: int posixemu_stat(const char *name, struct stat *statbuf)
1.1.1.2   root      351: {
1.1.1.3   root      352:     DWORD attr;
                    353:     FILETIME ft, lft;
                    354: 
                    355:     if ((attr = getattr(name,&ft,(size_t*)&statbuf->st_size)) == (DWORD)~0)
                    356:     {
                    357:        lasterror = GetLastError();
                    358:        return -1;
                    359:     }
                    360:     else
                    361:     {
                    362:        statbuf->st_mode = (attr & FILE_ATTRIBUTE_READONLY) ? FILEFLAG_READ: FILEFLAG_READ | FILEFLAG_WRITE;
                    363:        if (attr & FILE_ATTRIBUTE_ARCHIVE) statbuf->st_mode |= FILEFLAG_ARCHIVE;
                    364:        if (attr & FILE_ATTRIBUTE_DIRECTORY) statbuf->st_mode |= FILEFLAG_DIR;
                    365:        FileTimeToLocalFileTime(&ft,&lft);
                    366:        statbuf->st_mtime = (*(__int64 *)&lft-((__int64)(369*365+89)*(__int64)(24*60*60)*(__int64)10000000))/(__int64)10000000;
                    367:     }
1.1.1.2   root      368:     return 0;
                    369: }
1.1.1.3   root      370: 
                    371: int posixemu_chmod(const char *name, int mode)
                    372: {
                    373:     DWORD attr = FILE_ATTRIBUTE_NORMAL;
                    374:     if (mode & 0x05) attr |= FILE_ATTRIBUTE_READONLY; /* Delete (0x01) or Write (0x04) bits */
                    375:     if (mode & 0x10) attr |= FILE_ATTRIBUTE_ARCHIVE;
                    376: 
                    377:     if (SetFileAttributes(name,attr)) return 1;
                    378:     lasterror = GetLastError();
                    379: 
                    380:     return -1;
                    381: }
1.1.1.2   root      382: #endif
1.1.1.3   root      383: 
                    384: void tmToSystemTime( struct tm *tmtime, LPSYSTEMTIME systime )
                    385: {
                    386:     if( tmtime == NULL )
                    387:     {
1.1.1.4 ! root      388:        GetSystemTime( systime );
1.1.1.3   root      389:     }
                    390:     else
                    391:     {
1.1.1.4 ! root      392:        systime->wDay       = tmtime->tm_mday;
        !           393:        systime->wDayOfWeek = tmtime->tm_wday;
        !           394:        systime->wMonth     = tmtime->tm_mon + 1;
        !           395:        systime->wYear      = tmtime->tm_year + 1900;
        !           396:        systime->wHour      = tmtime->tm_hour;
        !           397:        systime->wMinute    = tmtime->tm_min;
        !           398:        systime->wSecond    = tmtime->tm_sec;
        !           399:        systime->wMilliseconds = 0;
1.1.1.3   root      400:     }
                    401: }
                    402: 
                    403: static int setfiletime(const char *name, unsigned int days, int minute, int tick)
                    404: {
                    405:     FILETIME LocalFileTime, FileTime;
                    406:     HANDLE hFile;
                    407:     int success;
                    408:     if ((hFile = CreateFile(name, GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE,NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, NULL)) == INVALID_HANDLE_VALUE)
                    409:     {
                    410:        lasterror = GetLastError();
                    411:        return 0;
                    412:     }
                    413: 
                    414:     *(__int64 *)&LocalFileTime = (((__int64)(377*365+91+days)*(__int64)1440+(__int64)minute)*(__int64)(60*50)+(__int64)tick)*(__int64)200000;
                    415:     
                    416:     if (!LocalFileTimeToFileTime(&LocalFileTime,&FileTime)) FileTime = LocalFileTime;
                    417:     
                    418:     if (!(success = SetFileTime(hFile,&FileTime,&FileTime,&FileTime))) lasterror = GetLastError();
                    419:     CloseHandle(hFile);
                    420:     
                    421:     return success;
                    422: }
                    423: 
                    424: int posixemu_utime( const char *name, struct utimbuf *time )
                    425: {
                    426:     int result = -1;
                    427:     long days, mins, ticks;
                    428: 
                    429:     get_time( time->actime, &days, &mins, &ticks );
                    430: 
                    431:     if( setfiletime( name, days, mins, ticks ) )
1.1.1.4 ! root      432:        result = 0;
1.1.1.3   root      433: 
                    434:        return result;
                    435: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.