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

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

unix.superglobalmegacorp.com

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