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