📄 dosutil.c
字号:
#ifdef __DJGPP__
#include <ctype.h>
#include <errno.h>
#include <setjmp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <io.h>
/*
#include "config.h"
#include "general.h"
#include "subst.h"
#include "externs.h"
#include "builtins/common.h"
*/
#include "dosutil.h"
static char *encode_drivename_inplace (char *);
#if defined (__MSDOS__)
#define ROOTDEV_COMPARE strnicmp
#else
#define ROOTDEV_COMPARE strncmp
#endif
int dosutil_path_separator = ';';
int dosutil_path_slash = '/';
int dosutil_path_expand = 0;
const char dev_str[] = "/dev/";
const int dev_str_len = sizeof(dev_str) - 1;
const int dosutil_encoded_drive_len_diff = 4;
char dosutil_tmpdir[PATH_MAX + 1];
size_t dosutil_tmpdir_len;
char *dosutil_tmpdir_template;
int dosutil_test_finds_exe = 0;
static char *need_fix_variables[] =
{
"PWD",
"OLDPWD",
"HOME",
"PATH",
"CDPATH",
"COMSPEC",
"MAILPATH",
"TMPDIR",
NULL,
};
static void dummy(void)
{
__dosexec_find_on_path (0,0,0);
__libc_termios_init();
}
char *
dosutil_maybe_encode_drivename (char *path)
{
return (dosutil_path_separator == ':') ? dosutil_encode_drivename (path) : path;
}
/* Translate filenames of the form 'x:/dir/file' to '/dev/x/dir1/file'.
Returns a new string. */
char *
dosutil_encode_drivename (char *path)
{
char *enc_path;
int len = strlen (path);
if (dosutil_is_dev_path(path))
{
if (path && path[1] == ':')
strcpy(path, path + 2);
return path;
}
enc_path = (char *)malloc (len + dosutil_encoded_drive_len_diff + 1);
strcpy (enc_path, dev_str);
enc_path[5] = path[0];
strcpy (enc_path + sizeof (dev_str), path + 2);
free (path);
return enc_path;
}
/* Translate filenames of the form 'x:/dir/file' to '/dev/x/dir1/file'.
Returns the same string that was passed in. This function assumes
there is enough space to handle the modified string. */
static char *
encode_drivename_inplace (char *path)
{
int len = strlen (path);
char drive = path[0];
memmove (path + 6, path + 2, len - 1);
memcpy (path, dev_str, sizeof(dev_str) - 1);
path[5] = drive;
return path;
}
/* Translates filenames of the form '/dev/x/dir/file' into 'x:/dir/file'. */
char *
dosutil_decode_drivename (char *path)
{
char *p = path;
p = (path && path[1] == ':') ? (path + 2) : path;
path[0] = p[5];
path[1] = ':';
strcpy (path + 2, p + 6);
return path;
}
/* Returns whether or not a path starts with '/dev/' */
int
dosutil_is_dev_path (const char *path)
{
if (path && path[1] == ':')
path += 2;
return ROOTDEV_COMPARE (dev_str, path, dev_str_len) == 0;
}
/* Returns whether or not a filename is in the form '/dev/x/dir1/file'. */
int
dosutil_is_encoded_drivename (const char *path)
{
if (path && path[1] == ':')
path += 2;
return (ROOTDEV_COMPARE (dev_str, path, dev_str_len) == 0
&& path[dev_str_len]
&& (path[dev_str_len + 1] == '/' || path[dev_str_len + 1] == '\0'));
}
/* Returns whether the pathname is the root directory. */
int
dosutil_is_root_directory_pathname (const char *path)
{
const char *p = (path && path[1] == ':') ? (path + 2) : path;
if (*p == '/' && p[1] == '\0')
return 1;
if (dosutil_is_encoded_drivename (path))
return (p[6] == '/' && p[7] == '\0');
}
char *
dosutil_make_import_path (char *value)
{
char *p, *newenv;
int newlen, pos;
if (value == NULL)
return NULL;
/* fix each element */
newlen = strlen (value) + 1;
newenv = malloc (newlen);
if (newenv != NULL)
{
char *to, *from;
/* copy to buffer */
from = value;
to = newenv;
while (*from)
{
if (*from != '\\')
*to = *from;
else
*to = '/';
++to;
++from;
}
*to = '\0';
for (p = newenv; p != NULL && *p; p = strchr (p + 1, ';'))
{
int drive_len = 0;
/* replace delimiter */
while (*p == ';')
*p++ = dosutil_path_separator;
if (*p == '\0')
break;
/* check drive name */
if (p[0] && p[1] == ':')
{
if (dosutil_path_separator == ':')
{
newlen += dosutil_encoded_drive_len_diff;
pos = p - newenv;
newenv = realloc (newenv, newlen);
if (newenv == NULL)
return NULL;
p = newenv + pos;
encode_drivename_inplace (p);
}
}
}
/* may need to convert slash to back-slash */
if (dosutil_path_slash == '\\')
dosutil_tobslash (newenv);
}
return newenv;
}
char *
dosutil_make_export_path (char *value)
{
char *p, *newenv;
int newlen, pos;
if (value == NULL)
return NULL;
/* fix each element */
newlen = strlen (value) + 1;
newenv = malloc (newlen);
if (newenv != NULL)
{
/* copy to buffer */
strcpy (newenv, value);
/* convert back-slash to slash */
dosutil_toslash (newenv);
for (p = newenv; p != NULL && *p; p = strchr (p + 1, dosutil_path_separator))
{
/* replace delimiter */
while (*p == dosutil_path_separator)
*p++ = ';';
if (*p == '\0')
break;
if (p[1] != dosutil_path_separator
&& dosutil_is_encoded_drivename(p))
{
/* Expand drive name */
dosutil_decode_drivename (p);
newlen -= dosutil_encoded_drive_len_diff;
pos = p - newenv;
newenv = realloc (newenv, newlen);
if (newenv == NULL)
return NULL;
p = newenv + pos;
/* Skip past colon after drive letter. */
p += 2;
}
}
/* convert slash to back-slash */
dosutil_tobslash (newenv);
}
return newenv;
}
void
dosutil_import_environment_variables (void)
{
char *p;
int i;
p = getenv ("PATH_SEPARATOR");
if (p != NULL)
{
if (*p != '\0' && *p != '/' && *p != '\\' && *p < 0x7f)
dosutil_path_separator = (int) *(unsigned char *) p;
}
#if 0
else
{
char buf[2];
buf[0] = dosutil_path_separator;
buf[1] = '\0';
setenv("PATH_SEPARATOR", buf, 1);
}
#endif
p = getenv ("PATH_EXPAND");
if (p != NULL)
{
if (*p != '\0' && (*p == 'y' || *p == 'Y'))
dosutil_path_expand = 1;
}
else
dosutil_path_expand = 0;
p = getenv (DOSUTIL_TEST_VAR_NAME);
if (p != NULL)
{
if (*p == 'y' || *p =='Y')
dosutil_test_finds_exe = 1;
}
}
int
dosutil_import_unixy_pathvar (char *name, char **path)
{
int i;
char *p;
for (i = 0; (p = need_fix_variables[i]) != NULL; i++)
{
if (strcmp (p, name) == 0)
break;
}
if (p == NULL)
return 0;
*path = dosutil_make_import_path (*path);
return 1;
}
char *
dosutil_add_slash (char *path)
{
char *top = path;
path += strlen (path);
if (path != top && path[-1] != '/')
{
*path++ = '/';
*path++ = '\0';
}
return top;
}
char *
dosutil_delete_slash (char *path)
{
char *top = path;
path += strlen (path);
if (path != top && path[-1] == '/')
path[-1] = '\0';
return top;
}
char *
dosutil_toslash (char *path)
{
char *p;
#if defined (USE_MULTIBYTE)
int mbsize;
#endif
for (p = path; *p; p++)
{
#if defined (USE_MULTIBYTE)
mbsize = mblen (p, MB_CUR_MAX);
if (mbsize > 1)
{
p += mbsize - 1;
continue;
}
else if (*p == '\\')
*p = '/';
#else
if (*p == '\\')
*p = '/';
#endif
}
return path;
}
char *
dosutil_tobslash (char *path)
{
char *p;
#if defined (USE_MULTIBYTE)
int mbsize;
#endif
for (p = path; *p; p++)
{
#if defined (USE_MULTIBYTE)
mbsize = mblen (p, MB_CUR_MAX);
if (mbsize > 1)
{
p += mbsize - 1;
continue;
}
else if (*p == '/')
*p = '\\';
#else
if (*p == '/')
*p = '\\';
#endif
}
return path;
}
char *
dosutil_tolower (char *path)
{
char *p;
#if defined (USE_MULTIBYTE)
int mbsize;
#endif
for (p = path; *p; p++)
{
#if defined (USE_MULTIBYTE)
mbsize = mblen (p, MB_CUR_MAX);
if (mbsize > 1)
{
p += mbsize - 1;
continue;
}
else if (isupper (*p))
*p = tolower (*p);
#else
if (isupper (*p))
*p = tolower (*p);
#endif
}
return path;
}
char *
dosutil_toupper (char *path)
{
char *p;
#if defined (USE_MULTIBYTE)
int mbsize;
#endif
for (p = path; *p; p++)
{
#if defined (USE_MULTIBYTE)
mbsize = mblen (p, MB_CUR_MAX);
if (mbsize > 1)
{
p += mbsize - 1;
continue;
}
else if (islower (*p))
*p = toupper (*p);
#else
if (islower (*p))
*p = toupper (*p);
#endif
}
return path;
}
char *
dosutil_fix_variable (char *vp)
{
char *p, *fixp, *newbuf;
int i;
if (vp == NULL)
return NULL;
p = strchr (vp, '=');
if (!p)
return vp;
*p = '\0';
fixp = dosutil_make_export_path (p + 1);
if (fixp != NULL)
{
newbuf = malloc (strlen (fixp) + strlen (vp) + 2);
if (newbuf != NULL)
{
#if defined (__MSDOS__) && 0
/* convert upper case */
if (strcmp (p, "PATH") == 0)
dosutil_toupper (fixp);
#endif
sprintf (newbuf, "%s=%s", vp, fixp);
free (vp);
vp = newbuf;
}
free (fixp);
}
return vp;
}
char *
dosutil_export_unixy_pathvar (char *path_var)
{
return dosutil_fix_variable (path_var);
}
char **
dosutil_get_import_variables (void)
{
char **p;
int i;
/* count need size */
for (i = 0; need_fix_variables[i] != NULL; i++)
;
p = malloc (i * sizeof (char*));
if (p != NULL)
{
for (i = 0; need_fix_variables[i] != NULL; i++)
p[i] = dosutil_make_export_path (get_string_value (need_fix_variables[i]));
}
return p;
}
void
dosutil_put_export_variables (char **vp)
{
SHELL_VAR *var;
int i;
if (vp == NULL)
return;
for (i = 0; need_fix_variables[i] != NULL; i++)
{
var = find_variable (need_fix_variables[i]);
if (var != NULL)
{
if (var->value != NULL)
free (var->value);
var->value = dosutil_make_import_path (vp[i]);
}
if (vp[i] != NULL)
free (vp[i]);
}
free (vp);
set_working_directory (get_string_value ("PWD"));
}
void dosutil_set_tmpdir(const char *bashpath)
{
char *tmpdirs[] = {"$TMPDIR", "$TEMP", "$TMP", "c:/tmp", ".", NULL};
char *tmp, *dir;
#if 0
char *tmpf;
#endif
int fd, i, len;
dosutil_tmpdir[0] = '\0';
dosutil_tmpdir_len = 0;
i = 0;
while (tmpdirs[i] != NULL)
{
if (tmpdirs[i][0] == '$')
{
dir = getenv(tmpdirs[i] + 1);
if (!(dir && *dir))
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -