Annotation of uae/src/od-win32/fsdb_win32.c, revision 1.1.1.5

1.1       root        1:  /*
                      2:   * UAE - The Un*x Amiga Emulator
                      3:   *
                      4:   * Library of functions to make emulated filesystem as independent as
                      5:   * possible of the host filesystem's capabilities.
                      6:   * This is the Win32 version.
                      7:   *
                      8:   * Copyright 1997 Mathias Ortmann
                      9:   * Copyright 1999 Bernd Schmidt
                     10:   */
                     11: 
                     12: #include "sysconfig.h"
                     13: #include "sysdeps.h"
                     14: 
                     15: #include "fsdb.h"
1.1.1.3   root       16: #include <windows.h>
1.1       root       17: 
1.1.1.2   root       18: /* these are deadly (but I think allowed on the Amiga): */
                     19: #define NUM_EVILCHARS 7
                     20: char evilchars[NUM_EVILCHARS] = { '\\', '*', '?', '\"', '<', '>', '|' };
                     21: 
1.1       root       22: /* Return nonzero for any name we can't create on the native filesystem.  */
                     23: int fsdb_name_invalid (const char *n)
                     24: {
1.1.1.2   root       25:     int i;
1.1       root       26:     char a = n[0];
                     27:     char b = (a == '\0' ? a : n[1]);
                     28:     char c = (b == '\0' ? b : n[2]);
1.1.1.2   root       29:     char d = (c == '\0' ? c : n[3]);
1.1.1.4   root       30:     int l = strlen (n);
1.1       root       31: 
                     32:     if (a >= 'a' && a <= 'z')
1.1.1.2   root       33:         a -= 32;
1.1       root       34:     if (b >= 'a' && b <= 'z')
1.1.1.2   root       35:         b -= 32;
1.1       root       36:     if (c >= 'a' && c <= 'z')
1.1.1.2   root       37:         c -= 32;
1.1       root       38: 
1.1.1.4   root       39:     if ((a == 'A' && b == 'U' && c == 'X' && l == 3) /* AUX  */
                     40:        || (a == 'C' && b == 'O' && c == 'N' && l == 3) /* CON  */
                     41:        || (a == 'P' && b == 'R' && c == 'N' && l == 3) /* PRN  */
                     42:        || (a == 'N' && b == 'U' && c == 'L' && l == 3) /* NUL  */
                     43:        || (a == 'L' && b == 'P' && c == 'T'  && (d >= '0' && d <= '9') && l == 4)  /* LPT# */
                     44:        || (a == 'C' && b == 'O' && c == 'M'  && (d >= '0' && d <= '9') && l == 4)) /* COM# */
1.1       root       45:        return 1;
1.1.1.4   root       46:   
                     47:     /* spaces and periods at the end are a no-no */
1.1.1.2   root       48:     i = strlen(n) - 1;
                     49:     if (n[i] == '.' || n[i] == ' ')
1.1       root       50:        return 1;
1.1.1.2   root       51: 
                     52:     /* these characters are *never* allowed */
                     53:     for (i = 0; i < NUM_EVILCHARS; i++) {
                     54:         if (strchr (n, evilchars[i]) != 0)
                     55:             return 1;
                     56:     }
                     57: 
                     58:     /* the reserved fsdb filename */
                     59:     if (strcmp (n, FSDB_FILE) == 0)
1.1       root       60:        return 1;
1.1.1.2   root       61:     return 0; /* the filename passed all checks, now it should be ok */
                     62: }
                     63: 
                     64: uae_u32 filesys_parse_mask(uae_u32 mask)
                     65: {
1.1.1.5 ! root       66:     return mask ^ 0xf;
1.1       root       67: }
                     68: 
                     69: /* For an a_inode we have newly created based on a filename we found on the
                     70:  * native fs, fill in information about this file/directory.  */
                     71: void fsdb_fill_file_attrs (a_inode *aino)
                     72: {
1.1.1.2   root       73:     int mode;
                     74: 
                     75:     if((mode = GetFileAttributes(aino->nname)) == 0xFFFFFFFF) return;
                     76:        
                     77:     aino->dir = (mode & FILE_ATTRIBUTE_DIRECTORY) ? 1 : 0;
1.1.1.5 ! root       78:     aino->amigaos_mode = A_FIBF_EXECUTE | A_FIBF_READ;
        !            79:     if (FILE_ATTRIBUTE_ARCHIVE & mode)
        !            80:        aino->amigaos_mode |= A_FIBF_ARCHIVE;
        !            81:     if (! (FILE_ATTRIBUTE_READONLY & mode))
        !            82:        aino->amigaos_mode |= A_FIBF_WRITE | A_FIBF_DELETE;
1.1.1.2   root       83:     aino->amigaos_mode = filesys_parse_mask(aino->amigaos_mode);
1.1       root       84: }
                     85: 
1.1.1.3   root       86: int fsdb_set_file_attrs (a_inode *aino, int mask)
1.1       root       87: {
                     88:     struct stat statbuf;
1.1.1.2   root       89:     uae_u32 mode=0, tmpmask;
1.1       root       90: 
1.1.1.2   root       91:     tmpmask = filesys_parse_mask(mask);
1.1.1.5 ! root       92: 
1.1       root       93:     if (stat (aino->nname, &statbuf) == -1)
1.1.1.2   root       94:        return ERROR_OBJECT_NOT_AROUND;
1.1.1.5 ! root       95: 
1.1       root       96:     /* Unix dirs behave differently than AmigaOS ones.  */
1.1.1.2   root       97:     /* windows dirs go where no dir has gone before...  */
1.1       root       98:     if (! aino->dir) {
1.1.1.5 ! root       99:        if ((tmpmask & (A_FIBF_READ | A_FIBF_DELETE)) == 0)
        !           100:            mode |= FILE_ATTRIBUTE_READONLY;
1.1.1.2   root      101:        if (tmpmask & A_FIBF_ARCHIVE)
                    102:            mode |= FILE_ATTRIBUTE_ARCHIVE;
1.1       root      103:        else
1.1.1.2   root      104:            mode &= ~FILE_ATTRIBUTE_ARCHIVE;
1.1       root      105: 
1.1.1.2   root      106:        SetFileAttributes(aino->nname, mode);
1.1       root      107:     }
                    108: 
                    109:     aino->amigaos_mode = mask;
                    110:     aino->dirty = 1;
                    111:     return 0;
                    112: }
                    113: 
                    114: /* Return nonzero if we can represent the amigaos_mode of AINO within the
                    115:  * native FS.  Return zero if that is not possible.  */
                    116: int fsdb_mode_representable_p (const a_inode *aino)
                    117: {
1.1.1.5 ! root      118:     int mask = aino->amigaos_mode;
        !           119:     int m1;
        !           120: 
1.1       root      121:     if (aino->dir)
                    122:        return aino->amigaos_mode == 0;
1.1.1.5 ! root      123: 
        !           124:     /* P or S set, or E or R clear, means we can't handle it.  */
        !           125:     if (mask & (A_FIBF_SCRIPT | A_FIBF_PURE | A_FIBF_EXECUTE | A_FIBF_READ))
        !           126:        return 0;
        !           127: 
        !           128:     m1 = A_FIBF_DELETE | A_FIBF_WRITE;
        !           129:     /* If it's rwed, we are OK... */
        !           130:     if ((mask & m1) == 0)
        !           131:        return 1;
        !           132:     /* We can also represent r-e-, by setting the host's readonly flag.  */
        !           133:     if ((mask & m1) == m1)
        !           134:        return 1;
        !           135:     return 0;
1.1       root      136: }
                    137: 
                    138: char *fsdb_create_unique_nname (a_inode *base, const char *suggestion)
                    139: {
                    140:     char *c;
                    141:     char tmp[256] = "__uae___";
1.1.1.2   root      142:     int i;
                    143: 
1.1       root      144:     strncat (tmp, suggestion, 240);
1.1.1.2   root      145:        
                    146:     /* replace the evil ones... */
                    147:     for (i=0; i < NUM_EVILCHARS; i++)
                    148:         while ((c = strchr (tmp, evilchars[i])) != 0)
                    149:             *c = '_';
1.1       root      150: 
                    151:     while ((c = strchr (tmp, '.')) != 0)
1.1.1.2   root      152:         *c = '_';
                    153:     while ((c = strchr (tmp, ' ')) != 0)
                    154:         *c = '_';
1.1       root      155: 
                    156:     for (;;) {
                    157:        char *p = build_nname (base->nname, tmp);
                    158:        if (access (p, R_OK) < 0 && errno == ENOENT) {
1.1.1.2   root      159:            write_log ("unique name: %s\n", p);
1.1       root      160:            return p;
                    161:        }
                    162:        free (p);
                    163: 
                    164:        /* tmpnam isn't reentrant and I don't really want to hack configure
                    165:         * right now to see whether tmpnam_r is available...  */
                    166:        for (i = 0; i < 8; i++) {
1.1.1.3   root      167:            tmp[i+8] = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"[rand () % 63];
1.1       root      168:        }
                    169:     }
                    170: }

unix.superglobalmegacorp.com

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