⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dosutil.c

📁 UNIX下SH的实现源码
💻 C
📖 第 1 页 / 共 2 页
字号:
#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 + -