|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.