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

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

unix.superglobalmegacorp.com

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