mirror of https://github.com/GnoConsortium/gno.git
224 lines
4.0 KiB
C
224 lines
4.0 KiB
C
/*
|
|
* libc/gno/map.c -- various mapping functions
|
|
*
|
|
* $Id: map.c,v 1.4 1999/07/03 14:37:36 gdr-ftp Exp $
|
|
*
|
|
* This file is formatted with tabstops every 8 columns
|
|
*/
|
|
|
|
#ifdef __ORCAC__
|
|
segment "libc_gno__";
|
|
#endif
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <errno.h>
|
|
#include <gno/gno.h>
|
|
|
|
#define GS_READ 0x0001
|
|
#define GS_WRITE 0x0002
|
|
#define GS_INVISIBLE 0x0004
|
|
#define GS_BACKUP 0x0020
|
|
#define GS_RENAME 0x0040
|
|
#define GS_DESTROY 0x0080
|
|
#define GS_MASK 0xFF18 /* complement of bitwise-OR of above GS- values */
|
|
|
|
static int __fileModeEmulation = 1; /* do we emulate Unix mode parameters? */
|
|
|
|
/*
|
|
* _getModeEmulation
|
|
*/
|
|
|
|
int
|
|
_getModeEmulation (void) {
|
|
return __fileModeEmulation;
|
|
}
|
|
|
|
/*
|
|
* _setModeEmulation
|
|
*/
|
|
|
|
int
|
|
_setModeEmulation (int newval) {
|
|
int result;
|
|
|
|
result = __fileModeEmulation;
|
|
__fileModeEmulation = !(newval == 0);
|
|
return result;
|
|
}
|
|
|
|
/*
|
|
* _mapMode2GS -- Take a Unix mode and return the GS/OS equivalent.
|
|
*
|
|
* Devin Reade <gdr@gno.org>
|
|
*/
|
|
|
|
mode_t
|
|
_mapMode2GS(mode_t oldmode) {
|
|
mode_t newmode = GS_BACKUP;
|
|
|
|
if (__fileModeEmulation == 0) {
|
|
return oldmode;
|
|
}
|
|
if (oldmode & S_IRUSR) {
|
|
newmode |= GS_READ;
|
|
}
|
|
if (oldmode & S_IWUSR) {
|
|
newmode |= GS_WRITE | GS_RENAME | GS_DESTROY;
|
|
}
|
|
return newmode;
|
|
}
|
|
|
|
/*
|
|
* _mapMode2Unix -- Take a GS/OS mode and return the Unix equivalent.
|
|
*
|
|
* Devin Reade <gdr@gno.org>
|
|
*/
|
|
|
|
mode_t
|
|
_mapMode2Unix(mode_t oldmode) {
|
|
mode_t newmode = S_IXUSR | S_IXGRP | S_IXOTH;
|
|
int mask;
|
|
|
|
if (__fileModeEmulation == 0) {
|
|
return oldmode;
|
|
}
|
|
if (oldmode & GS_READ) {
|
|
newmode |= S_IRUSR | S_IRGRP | S_IROTH;
|
|
}
|
|
if ((oldmode & GS_WRITE) && (oldmode & GS_RENAME) &&
|
|
(oldmode & GS_DESTROY)) {
|
|
newmode |= S_IWUSR | S_IWGRP | S_IWOTH;
|
|
}
|
|
|
|
/* get the umask */
|
|
umask((mask = umask(0)));
|
|
return newmode & mask;
|
|
}
|
|
|
|
/*
|
|
* _setPathMapping -- control whether or not we map pathnames
|
|
*
|
|
* Devin Reade <gdr@gno.org>
|
|
*/
|
|
|
|
static int __force_slash = 0; /* default: no pathname mapping */
|
|
|
|
int
|
|
_setPathMapping (int val) {
|
|
int previous = __force_slash;
|
|
|
|
__force_slash = (val != 0);
|
|
return previous;
|
|
}
|
|
|
|
int
|
|
_getPathMapping (void) {
|
|
return __force_slash;
|
|
}
|
|
|
|
/*
|
|
* _mapPath -- map all occurances of ':' to '/'
|
|
*
|
|
* Devin Reade <gdr@gno.org>
|
|
*/
|
|
|
|
char *
|
|
_mapPath (char *pathname) {
|
|
char *p;
|
|
int foundSlash, foundColon;
|
|
|
|
if (! __force_slash) {
|
|
return pathname;
|
|
}
|
|
|
|
/* validity check */
|
|
foundSlash = foundColon = 0;
|
|
for (p = pathname; *p != '\0'; p++) {
|
|
if (*p == ':') foundColon = 1;
|
|
if (*p == '/') foundSlash = 1;
|
|
}
|
|
if (foundSlash && foundColon) {
|
|
return NULL;
|
|
}
|
|
for (p = pathname; *p != '\0'; p++) {
|
|
if (*p == ':') *p = '/';
|
|
}
|
|
return pathname;
|
|
}
|
|
|
|
/*
|
|
* _mapPathGS -- map all occurances of ':' to '/'
|
|
*
|
|
* Devin Reade <gdr@gno.org>
|
|
*/
|
|
|
|
GSStringPtr
|
|
_mapPathGS (GSStringPtr pathname) {
|
|
char *p, *q;
|
|
int foundSlash, foundColon;
|
|
|
|
if (! __force_slash || pathname->length == 0) {
|
|
return pathname;
|
|
}
|
|
|
|
/* validity check */
|
|
foundSlash = foundColon = 0;
|
|
p = pathname->text;
|
|
q = p + pathname->length;
|
|
while (p < q) {
|
|
if (*p == ':') foundColon = 1;
|
|
if (*p == '/') foundSlash = 1;
|
|
p++;
|
|
}
|
|
if (foundSlash && foundColon) {
|
|
return NULL;
|
|
}
|
|
p = pathname->text;
|
|
while (p < q) {
|
|
if (*p == ':') *p = '/';
|
|
p++;
|
|
}
|
|
return pathname;
|
|
}
|
|
|
|
/*
|
|
* _mapErr -- Take a GS/OS error and maps it to a kernel errno. If there
|
|
* is no direct mapping, then map it to EIO.
|
|
*/
|
|
|
|
int
|
|
_mapErr (int err) {
|
|
int ret;
|
|
if (!err) {
|
|
return 0;
|
|
}
|
|
if ((err & 0xff00) == 0x4300) {
|
|
/* GNO already mapped the error */
|
|
return (err & 0x00ff);
|
|
}
|
|
switch (err) {
|
|
case 0x43: ret = EBADF; break;
|
|
|
|
case 0x44:
|
|
case 0x45:
|
|
case 0x46: ret = ENOENT; break;
|
|
|
|
case 0x47:
|
|
case 0x50: ret = EEXIST; break;
|
|
|
|
case 0x48:
|
|
case 0x49: ret = ENOSPC; break;
|
|
case 0x4A: ret = ENOTDIR; break;
|
|
|
|
case 0x4B:
|
|
case 0x4F:
|
|
case 0x53: ret = EINVAL; break;
|
|
case 0x54: ret = ENOMEM; break;
|
|
case 0x4E: ret = EACCES; break;
|
|
case 0x58: ret = ENOTBLK; break;
|
|
default: ret = EIO; break;
|
|
}
|
|
return ret;
|
|
}
|