Example #1
0
char *curDateLong(void)
{
	struct dosdate_t d;
	char *date, *h, *p;

	_dos_getdate(&d);

	if((date = nls_makedate(0, d.year, d.month, d.day)) == 0) {
		error_out_of_memory();
		return 0;
	}

	if((h = getString(TEXT_WEEKDAY_SHORT_NAME_SUNDAY + d.dayofweek)) == 0) {
		free(date);
		error_out_of_memory();
		return 0;
	}

	if((p = realloc(h, strlen(h) + strlen(date) + 2)) == 0) {
		free(h);
		free(date);
		error_out_of_memory();
		return 0;
	}

	strcpy(stpcat(p, " "), date);
	free(date);

	return p;
}
Example #2
0
int copyFiles(struct CopySource *h)
{ char *fnam, *ext, *dst;
  int differ, rc;

  if(destIsDir) {
    if(!dfnsplit(h->fnam, 0, 0, &fnam, &ext)) {
      error_out_of_memory();
      return 0;
    }
    dst = dfnmerge(0, 0, destFile, fnam, ext);
    free(fnam);
    free(ext);
    if(!dst) {
      error_out_of_memory();
      return 0;
    }
  } else
    dst = destFile;

  rc = 0;

  if((differ = samefile(h->fnam, dst)) < 0)
    error_out_of_memory();
  else if(!differ)
    rc = copy(dst, h->fnam, h, 'w');
  else if(h->app)
    rc = copy(dst, h->fnam, h->app, 'a');
  else
    error_selfcopy(dst);

  if(destIsDir)
    free(dst);
  return rc;
}
Example #3
0
int dir_print_body(char *arg, unsigned long *dircount)
{	int rv;
	unsigned long filecount, bytecount;
	char *pattern, *cachedPattern;
	char *p;

		/* Modified to pre-allocate path to 270 bytes so that
		   we don't have to realloc() it later.  That was causing
		   "DIR /S" not to work properly.  The path variable cannot
		   be reallocated once dir_list() is called, because dir_list()
		   is recursive.  This will also help to reduce memory
		   fragmentation. */
	if((p = dfnfullpath(arg)) == NULL) {
		error_out_of_memory();
		return E_NoMem;
	}
	if((path = realloc(p, 270*sizeof(char))) == NULL) {
		free(p);
		error_out_of_memory();
		return E_NoMem;
	}

	filecount = bytecount = 0;

	/* print the header */
	if((rv = dir_print_header(toupper(path[0]) - 'A')) == 0) {
		/* There are some directory specs that are not detected by
			dfnstat() as they are no part of the filesystem in DOS */
		pattern = dfnfilename(path);
		assert(p);
		if(!*pattern || (dfnstat(path) & DFN_DIRECTORY) != 0) {
			pattern = strchr(pattern, '\0');
			if(pattern[-1] != '\\')
				++pattern;
			rv = dir_list(pattern - path, "*.*", dircount, &filecount
			 , &bytecount
			 );
		} else {
			if((cachedPattern = strdup(pattern)) == NULL) {
				error_out_of_memory();
				rv = E_NoMem;
			} else {
				rv = dir_list(pattern - path, cachedPattern, dircount
				 , &filecount, &bytecount
				 );
				free(cachedPattern);
			}
		}
	}

	free(path);
	return rv || (optS? print_total(filecount, bytecount): 0);
}
Example #4
0
int cmd_fddebug(char *param)
{
	switch(onoffStr(param)) {
  	default: {
  		FILE *f;
  		char *p;

  		if((p = strdup(trimcl(param))) == 0) {
  			error_out_of_memory();
  			return 1;
  		}

  		if(stricmp(param, "stderr") == 0) f = stderr;
  		else if(stricmp(param, "stdout") == 0) f = stdout;
  		else if((f = fopen(param, "at")) == 0) {
  			error_open_file(param);
  			return 2;
  		}
		if(dbg_logfile != stderr && dbg_logfile != stdout)
			fclose(dbg_logfile);
		dbg_logfile = f;
		free(dbg_logname);
		dbg_logname = p;
		/* FALL THROUGH */
	}
  	case OO_On:		fddebug = 1;	break;
	case OO_Null:	case OO_Empty:
		displayString(TEXT_MSG_FDDEBUG_STATE, fddebug ? D_ON : D_OFF);
		displayString(TEXT_MSG_FDDEBUG_TARGET
		 , dbg_logname? dbg_logname: "stdout");
		break;
  	case OO_Off:	fddebug = 0;	break;
	}
  return 0;
}
Example #5
0
/*
 * Scan all leading options
 */
int leadOptions(char **Xline, optScanner fct, void * arg)
{ int ec = E_None;
  char *p, *q, *line;

  assert(Xline && *Xline);

  p = *Xline;

  while(*(line = skipdm(p))) {
    q = unquote(line, p = skipwd(line));
    if(!q) {
      error_out_of_memory();
      return E_NoMem;
    }

    if(!isoption(q)
     || ((ec = scanOption(fct, arg, q)) != E_None
          && ec != E_Ignore)) {
      free(q);
      break;
    }

    free(q);
  }

  *Xline = line;

  return ec;
}
Example #6
0
int addSource(char *p)
{ struct CopySource *h;
  char *q;

  assert(p);
  q = strtok(p, "+");
  assert(q && *q);

  if(appendToFile) {
    appendToFile = 0;
    if(!lastApp) {
      error_leading_plus();
      return 0;
    }
  } else {      /* New entry */
    if((h = malloc(sizeof(struct CopySource))) == 0) {
      error_out_of_memory();
      return 0;
    }
    if(!last)
      last = lastApp = head = h;
    else
      last = lastApp = last->nxt = h;

    h->nxt = h->app = 0;
    h->fnam = q;
    h->flags = cpyFlags();
    if((q = strtok(0, "+")) == 0)   /* no to-append file */
      return 1;
  }

  /* all the next files are to be appended to the source in "last" */
  assert(q);
  assert(lastApp);
  do {
    if((h = malloc(sizeof(struct CopySource))) == 0) {
      error_out_of_memory();
      return 0;
    }
    h->fnam = q;
    h->flags = cpyFlags();
    h->app = 0;
    lastApp = lastApp->app = h;
  } while((q = strtok(0, "+")) != 0);

  return 1;
}
Example #7
0
int dir_print_body(char *arg)
{ int rv;
  unsigned long dircount, filecount, bytecount;
  char *pattern, *cachedPattern;

dprintf( ("[DIR: path=\"%s\"]\n", arg) );
    if((path = dfnexpand(arg, NULL)) == NULL) {
      error_out_of_memory();
      return E_NoMem;
    }

  dircount = filecount = bytecount = 0;
  pattern = strchr(path, '\0');
  if(pattern[-1] == '\\') {
  	/* trailing backslash means that this has to be a directory */
  	if(!StrAppChr(path, '.')) {
      error_out_of_memory();
      return E_NoMem;
    }
   }

dprintf( ("[DIR: absolute path=\"%s\"]\n", path) );

  /* print the header */
  if ((rv = dir_print_header(toupper(path[0]) - 'A')) == 0) {
    if(dfnstat(path) & DFN_DIRECTORY) {
      pattern = strchr(path, '\0');
      if(pattern[-1] != '\\')
        ++pattern;
      rv = dir_list(pattern - path, "*.*", &dircount, &filecount
     , &bytecount);
    } else {
    if((cachedPattern = strdup(pattern = dfnfilename(path))) == NULL) {
      error_out_of_memory();
      rv = E_NoMem;
    }
    else {
       rv = dir_list(pattern - path, cachedPattern, &dircount, &filecount
        , &bytecount);
       free(cachedPattern);
    }
   }
  }

  free(path);
  return rv;
}
Example #8
0
void *emalloc(const size_t size)
{	void *h;

	if((h = malloc(size)) == 0)
		error_out_of_memory();

	return h;
}
Example #9
0
char *edupstr(const char far* const s)
{	void *h;

	if((h = _fdupstr(s)) == 0)
		error_out_of_memory();

	return h;
}
Example #10
0
static VOID ConWrite(TCHAR *str, DWORD len, DWORD nStdHandle)
{
	DWORD dwWritten;
	HANDLE hOutput = GetStdHandle(nStdHandle);

	if (WriteConsole(hOutput, str, len, &dwWritten, NULL))
		return;

	/* We're writing to a file or pipe instead of the console. Convert the
	 * string from TCHARs to the desired output format, if the two differ */
	if (bUnicodeOutput)
	{
#ifndef _UNICODE
		WCHAR *buffer = cmd_alloc(len * sizeof(WCHAR));
		if (!buffer)
		{
			error_out_of_memory();
			return;
		}
		len = MultiByteToWideChar(OutputCodePage, 0, str, len, buffer, len);
		str = (PVOID)buffer;
#endif
		WriteFile(hOutput, str, len * sizeof(WCHAR), &dwWritten, NULL);
#ifndef _UNICODE
		cmd_free(buffer);
#endif
	}
	else
	{
#ifdef _UNICODE
		CHAR *buffer = cmd_alloc(len * MB_LEN_MAX * sizeof(CHAR));
		if (!buffer)
		{
			error_out_of_memory();
			return;
		}
		len = WideCharToMultiByte(OutputCodePage, 0, str, len, buffer, len * MB_LEN_MAX, NULL, NULL);
		str = (PVOID)buffer;
#endif
		WriteFile(hOutput, str, len, &dwWritten, NULL);
#ifdef _UNICODE
		cmd_free(buffer);
#endif
	}
}
Example #11
0
/*
 * setBatchParams builds a parameter list in newly allocated memory.
 * The parameters consist of null terminated strings with a final
 * NULL character signalling the end of the parameters.
 */
int setBatchParams(char *s)
{
  if((bc->params = split(s, &bc->numParams)) == 0)
  {
    error_out_of_memory();
    return 0;
  }
  return 1;
}
Example #12
0
void lastDirSet(void)
{	char *dir;

	if((dir = cwd(0)) != 0) {
		ctxtSet(CTXT_TAG_LASTDIR, 1, dir);
		free(dir);
	} else
		error_out_of_memory();
}
Example #13
0
void display_errno_fnam_error(const char * const fnam)
{
	assert(fnam);

	switch(errno) {
	case ERANGE:	dprintf( ("[FATAL: dfnpath() buffer too small]\n") );
	case ENOMEM:	error_out_of_memory(); break;
	default:		error_sfile_not_found(fnam);
	}
}
Example #14
0
char *curTime(void)
{	char *time;
	struct dostime_t t;

    _dos_gettime(&t);

    time = nls_maketime(0, t.hour, t.minute, t.second, t.hsecond);
    if(!time)
    	error_out_of_memory();

    return time;
}
Example #15
0
/*
 *	Retreive the current working directory including drive letter
 *	Returns in a dynamically allocated buffer (free'ed by the caller)
 *	on error: Displays "out of memory"
 */
char *cwd(int drive)
{	char *h;

	if((h = dfnpath(drive)) != 0)
		return h;

	if(drive)
		error_no_cwd(drive);
	else error_out_of_memory();

	return 0;
}
Example #16
0
int cmd_set(char *param)
{	char *value;
	char *promptBuf = 0;
	int ret;

	optC = promptUser = 0;

	if(leadOptions(&param, opt_set, 0) != E_None)
		return 1;

	switch(breakVarAssign(ctxtEnvironment, param, &value)) {
	case 1:			/* no equal sign */
		error_syntax(0);
		return 1;
	case 0:			/* displayed */
		return 0;
#ifdef DEBUG
	case 2: break;
	default:
		dprintf(("[SET: Invalid response from breakVarAssign()]\n"));
		return 1;
#endif
	}

	if(promptUser) {	/* -> Display the value, then read and assign */
		assert(value);
		fputs(value, stdout);
		promptBuf = malloc(promptBuffer);
		if(!promptBuf) {
			error_out_of_memory();
			return E_NoMem;
		}
		fgets(promptBuf, promptBuffer, stdin);
		if(cbreak) {
			free(promptBuf);
			return E_CBreak;
		}
		value = strchr(promptBuf, '\0');
		while(--value >= promptBuf && (*value == '\n' || *value == '\r'));
		value[1] = '\0';	/* strip trailing newlines */
		value = promptBuf;
	}

	/* If the value is just blanks, it means to delete the value;
		but otherwise even leading and trailing spaces must be kept */
	if(is_empty(value))
		value = 0;

	ret = chgEnvCase(optC, param, value);
	free(promptBuf);
	return ret;
}
Example #17
0
int cmd_time(char *rest)
{
  struct dostime_t t;
  char s[40];
  int ec;

  noPrompt = 0;

  if((ec = leadOptions(&rest, opt_date, NULL)) != E_None)
      return ec;

  if (!*rest)
  {
	char *time;
    _dos_gettime(&t);

    time = nls_maketime(0, t.hour, t.minute, t.second, t.hsecond);
    if(!time) {	
    	error_out_of_memory();
    	return 1;
    }
    displayString(TEXT_MSG_CURRENT_TIME, time);
    free(time);
    rest = NULL;
  }

  while (1)
  {
    if (rest)
    {
      if (parsetime(rest))
        return 0;
    } else {
		if(noPrompt) return 0;

      if ((rest = getMessage(TEXT_MSG_ENTER_TIME)) == NULL)
        return 1;

      fputs(rest, stdout);
      free(rest);
      fgets(s, sizeof(s), stdin);
      if (cbreak)
        return 1;
      if (parsetime(s))
        return 0;
    }
    displayString(TEXT_ERROR_INVALID_TIME);
    // force input the next time around.
    rest = NULL;
  }
}
Example #18
0
int optScanString_(const char * const optstr, int bool, const char *arg, char **value)
{
  assert(optstr);
  assert(value);

  if(!arg) {
    error_opt_noarg(optstr);
    return E_Useage;
  }
  free(*value);
  if((*value = strdup(arg)) == NULL) {
    error_out_of_memory();
    return E_NoMem;
  }
  return 0;
}
Example #19
0
static int directory_handler(char *rest,
                      int (*func) (const char *), char *fctname)
{ char **argv, *dir;
  int argc, opts;

  assert(func);

  if((argv = scanCmdline(rest, NULL, NULL, &argc, &opts)) == NULL)
    return 1;


  /* if doing a CD and no parameters given, print out current directory */
  if (func == chdir && argc == 0)
  {
    if((dir = dfnpath(0)) == NULL) {
      error_out_of_memory();
      freep(argv);
      return 1;
    }
    else {
      puts(dir);
      free(dir);
    }
  } else if(argc != 1) {
  error_req_param_missing();
    freep(argv);
    return 1;
  }
  else {
    assert(argv[0]);
    dir = strchr(argv[0], '\0');
  /* take off trailing \ if any, but ONLY if dir is not the root dir */
    if(dir > &argv[0][1] && *--dir == '\\' && dir[-1] != ':')
      *dir = '\0';

    dprintf(("%s: '%s'\n", fctname, argv[0]));
    if (func(argv[0]) != 0)
    {
      perror(fctname);
      freep(argv);
      return 1;
    }
  }

  freep(argv);
  return 0;
}
Example #20
0
int cmd_goto(char *rest)
{
/*
 * Perform GOTO command.
 *
 * Only valid if batch file current.
 */

  char *tmp;

  while(bc && bc->forvar)   /* is FOR context */
    exit_batch();       /* remove it */

  if (bc == NULL)
  {
    /*!! not in batch error */

    return 1;
  }
  assert(rest);

  if(*rest == ':')    /* some old DOS shell excepts a colon */
    rest = skipdm(rest + 1);

  if (*rest == '\0')
  {
    displayString(TEXT_ERROR_NO_GOTO_LABEL);
    exit_batch();
    return 1;
  }

  tmp = skip_word(rest);
  *tmp = '\0';

  tmp = strdup(rest);
  if (!tmp)
  {
    error_out_of_memory();
    return 1;
  }

  /* Restart the batch file from the beginning */
  bc->brewind = 1;
  bc->blabel = tmp;

  return 0;
}
Example #21
0
/*  Create/Clear/Chain all fields of the structure */
struct bcontext *newBatchContext(void)
{
  struct bcontext *b;

  b = malloc(sizeof(*b));
  if (!b)
  {
    error_out_of_memory();
    return 0;
  }

  initBatchContext(b);
  b->echo = echo;               /* a new context must always preserve the
                                   current ECHO state */

  b->prev = bc;
  return bc = b;
}
Example #22
0
LPTSTR BatchParams (LPTSTR s1, LPTSTR s2)
{
    LPTSTR dp = (LPTSTR)cmd_alloc ((_tcslen(s1) + _tcslen(s2) + 3) * sizeof (TCHAR));

    /* JPP 20-Jul-1998 added error checking */
    if (dp == NULL)
    {
        error_out_of_memory();
        return NULL;
    }

    if (s1 && *s1)
    {
        s1 = _stpcpy (dp, s1);
        *s1++ = _T('\0');
    }
    else
        s1 = dp;

    while (*s2)
    {
        BOOL inquotes = FALSE;

        /* Find next parameter */
        while (_istspace(*s2) || (*s2 && _tcschr(_T(",;="), *s2)))
            s2++;
        if (!*s2)
            break;

        /* Copy it */
        do
        {
            if (!inquotes && (_istspace(*s2) || _tcschr(_T(",;="), *s2)))
                break;
            inquotes ^= (*s2 == _T('"'));
            *s1++ = *s2++;
        } while (*s2);
        *s1++ = _T('\0');
    }

    *s1 = _T('\0');

    return dp;
}
Example #23
0
int ctxtChgSize(unsigned tosize)
{	ctxt_t new_context;

	assert(tosize);

	env_resizeCtrl = ENV_USEUMB | ENV_FIRSTFIT | ENV_ALLOWMOVE;
  if(forceLow)
	  env_resizeCtrl &= ~ENV_USEUMB;
	new_context = ctxt? env_setsize(ctxt, tosize)	/* alter context */
	                  : env_create(tosize);			/* new context */

	if(new_context) {
		ctxt = new_context;
		return E_None;
	}

	error_out_of_memory();
	return E_NoMem;
}
Example #24
0
int ecMkV1C(const char * const str, ...)
{	char *line, *verbatim;
	va_list ap;
	int rv;

	if((verbatim = ecMkVerbatimStr(str)) == 0)
		return E_NoMem;
	if((line
	 = StrConcat(5, "%@VERBATIM(", verbatim, ")", str, verbatim)) == 0) {
		error_out_of_memory();
		myfree(verbatim);
		return E_NoMem;
	}

	myfree(verbatim);
	va_start(ap, str);
	rv = ecMkvcmd(lflag_echo? 0: EC_CMD_SILENT, line, ap);
	myfree(line);
	return rv;
}
Example #25
0
int cmd_pushd(char *param)
{	char *curdir;
	int rc;

	if((curdir = cwd(0)) == 0) {
		error_out_of_memory();
		return 1;
	}

	rc = ctxtPush(CTXT_TAG_DIRSTACK, curdir);
	myfree(curdir);

	if(rc == E_None) {
		/* Change to directory specified on command line */
		if(param && *param)
			return cmd_cdd(param);
		return 0;
	}

	return 1;
}
Example #26
0
static INT
PushDirectory (LPTSTR pszPath)
{
	LPDIRENTRY lpDir = cmd_alloc(FIELD_OFFSET(DIRENTRY, szPath[_tcslen(pszPath) + 1]));
	if (!lpDir)
	{
		error_out_of_memory ();
		return -1;
	}

	lpDir->prev = NULL;
	lpDir->next = lpStackTop;
	if (lpStackTop == NULL)
		lpStackBottom = lpDir;
	else
		lpStackTop->prev = lpDir;
	lpStackTop = lpDir;

	_tcscpy(lpDir->szPath, pszPath);

	nStackDepth++;

	return nErrorLevel = 0;
}
Example #27
0
int ctxtPop(const Context_Tag tag, char ** const Xbuf)
{	ctxt_info_t *info;
	char *buf;

	ctxtCheckInfoTag(tag);
	assert(Xbuf);

	info = &CTXT_INFO_STRUCT(tag);
	while(info->c_nummax > info->c_nummin)
		switch(ctxtGet(1, tag, info->c_nummax--, &buf)) {
		case 0:			/* OK */
			*Xbuf = buf;
			return 1;
		case 1:			/* no such entry */
			break;		/* --> ifgnore silently */
		case 2:			/* out of memory */
			error_out_of_memory();
			return 0;	/* will case "context empty" message */
		}

	/* Nothing in the stack ==> make sure it's consistent */
	ctxtClear(tag);
	return 0;
}
Example #28
0
int initialize(void)
{
  int comPath;                /* path to COMMAND.COM (for COMSPEC/reload) */
  char *newTTY;                 /* what to change TTY to */
  int showinfo;                 /* show initial info only if no command line options */
  int key;

  int ec;           /* error code */
  unsigned offs;        /* offset into environment segment */

  int cmdlen;         /* length of command line */
  char *cmdline;        /* command line duplicated into heap */
  char *p, *h, *q;
#ifdef FEATURE_CALL_LOGGING
  FILE *f;
#endif

/* Set up the host environment of COMMAND.COM */

  /* Install the ^Break handler (see chkCBreak() for more details) */
  extern void initCBreakCatcher(void);
  initCBreakCatcher();

  /* Install INT 24 Critical error handler */
  init_error_handler();

  /* DOS shells patch the PPID to the own PID, how stupid this is, however,
    because then DOS won't terminate them, e.g. when a Critical Error
    occurs that is not detected by COMMAND.COM */

  oldPSP = OwnerPSP;
  atexit(exitfct);
  OwnerPSP = _psp;

  /* Some elder DOSs may not pass an initialzied environment segment */
  if (env_glbSeg && !isMCB(SEG2MCB(env_glbSeg)))
    env_setGlbSeg(0);       /* Disable the environment */

/* Now parse the command line parameters passed to COMMAND.COM */
  /* Preparations */
  newTTY = NULL;
  comPath = tracemode = 0;
  showinfo = 1;

  /* Because FreeCom should be executed in a DOS3+ compatible
    environment most of the time, it is assumed that its path
    can be determined from the environment.
    This has the advantage that the string area is accessable
    very early in the run.
    The name of the current file is string #0. */
  if((offs = env_string(0, 0)) != 0)    /* OK, environment filled */
    grabComFilename(0, (char far *)MK_FP(env_glbSeg, offs));

  /* Aquire the command line, there are three possible sources:
    1) DOS command line @PSP:0x80 as pascal string,
    2) extended DOS command line environment variable CMDLINE,
      if peekb(PSP, 0x80) == 127,&
    3) MKS command line @ENV:2, if peekb(ENV, 0) == '~'

    Currently implemented is version #1 only
  */
  cmdlen = peekb(_psp, 0x80);
  if(cmdlen < 0 || cmdlen > 126) {
    error_corrupt_command_line();
    cmdlen = 0;
  }
    /* duplicate the command line into the local address space */
  if((cmdline = malloc(cmdlen + 1)) == NULL) {
    error_out_of_memory();  /* Cannot recover from this problem */
    return E_NoMem;
  }
  _fmemcpy((char far*)cmdline, MK_FP(_psp, 0x81), cmdlen);
  cmdline[cmdlen] = '\0';
#ifdef FEATURE_CALL_LOGGING
  if((f = fopen(logFilename, "at")) == NULL) {
    fprintf(stderr, "Cannot open logfile: \"%s\"\n", logFilename);
    exit(125);
  }

  putc('"', f);
  if(ComPath)   /* path to command.com already known */
    fputs(ComPath, f);
  putc('"', f);
  putc(':', f);

  fputs(cmdline, f);
  putc('\n', f);
  fclose(f);
#endif

  p = cmdline;    /* start of the command line */
  do {
  ec = leadOptions(&p, opt_init, NULL);
  if(ec == E_NoOption) {    /* /C or /K */
    assert(p && *p);
    if(!isoption(p)) {
      error_quoted_c_k();
      p = NULL;
      break;
    }
    assert(p[1] && strchr("kKcC", p[1]));
    p += 2;   /* p := start of command line to execute */
    break;
  } else if(ec != E_None) {
        showhelp = 1;
    p = NULL;
    break;
  }

  assert(p && !isoption(p) && !isspace(*p));
  if(!*p) {
    p = NULL;
    break;      /* end of line reached */
  }
  q = unquote(p, h = skip_word(p));
  p = h;      /* Skip this word */
  if(!q) {
    error_out_of_memory();
    p = NULL;
    break;
  }
  if(!comPath) {      /* 1st argument */
    grabComFilename(1, (char far*)q);
    comPath = 1;
    free(q);
  } else if(!newTTY) {  /* 2nd argument */
#ifdef INCLUDE_CMD_CTTY
    newTTY = q;
#else
      error_ctty_excluded();
    free(q);
#endif
      } else {
        error_too_many_parameters(q);
        showhelp = 1;
        free(q);
        break;
      }
   } while(1);

   /*
    * Now:
    * + autoexec: AUTOEXEC.BAT file to be executed if /P switch
    *   is enabled; if NULL, use default
    * + comPath: user-defined PATH to COMMAND.COM; if NULL, use
    *   the one from the environment
    * + newTTY: the name of the device to be CTTY'ed; if NULL,
    *   no change
    * + p: pointer to the command to be executed:
    *   *p == 'c' or 'C' --> spawn command, then terminate shell
    *   *p == 'k' or 'K' --> spawn command, then go interactive
    *   &p[1] --> command line, unless the first character is an
    *   argument character
    */

/* Now process the options */

#ifdef INCLUDE_CMD_CTTY
  if (newTTY) {                   /* change TTY as early as possible so the caller gets
                                   the messages into the correct channel */
    cmd_ctty(newTTY);
    free(newTTY);
  }
#endif

  if(!ComPath) {
    /* FreeCom is unable to find itself --> print error message */
    /* Emergency error */
    puts("You must specify the complete path to " COM_NAME);
    puts("as the first argument of COMMAND,");
    puts("for instance: C:\\FDOS");
    return E_Useage;
  }

  /* First of all, set up the environment */
  env_resizeCtrl |= ENV_USEUMB | ENV_ALLOWMOVE;
  if (envSize < 0)
    envSize = 32767;        /* Numeric overflow (number > 32767 specified) */
  else if (envSize < 256)
    envSize = 256;          /* Minimum size of 256. */
	if(envSize > env_resize(0, 0))	/* Test if to enlarge environment */
		env_setsize(0, envSize);
    /* Set the COMSPEC variable. */
#if 0
  if (chgEnv("COMSPEC", ComPath)) error_env_var("COMSPEC");
#else
  if (chgEnv("COMSPEC", ComPath)) {
    /* Failed to add this variable, the most likely problem should be that
      the environment is too small --> it is increased and the
      operation is redone */
    env_resize(0, strlen(ComPath) + 10);
    if (chgEnv("COMSPEC", ComPath))
    error_env_var("COMSPEC");
  }
#endif

  if(internalBufLen)
    error_l_notimplemented();
  if(inputBufLen)
    error_u_notimplemented();

  if(tracemode)
    showinfo = 0;

  if (showhelp)
    displayString(TEXT_CMDHELP_COMMAND);

  if ((showhelp || exitflag) && canexit)
    return E_None;

  /* Now the /P option can be processed */
  if (!canexit)
  {
    char *autoexec;

    autoexec = user_autoexec? user_autoexec: AUTO_EXEC;

    showinfo = 0;
    short_version();

    /* JP: changed so that if autoexec does not exist, then don't ask
       to trace or bypass.
     */
    if (exist(autoexec))
    {
      printf("\nPress F8 for trace mode, or F5 to bypass %s... ", autoexec);
      key = WaitForFkeys();
      putchar('\n');

      if (key == KEY_F8)
      {
        tracemode = 1;
      }

      if (key == KEY_F5)
      {
        printf("Bypassing %s\n", autoexec);
      }
      else
        process_input(1, autoexec);
    }
    else
    {
      if(user_autoexec)
        printf("%s not found.\n", autoexec);
#ifdef INCLUDE_CMD_DATE
      cmd_date(NULL);
#endif
#ifdef INCLUDE_CMD_TIME
      cmd_time(NULL);
#endif
    }

    free(user_autoexec);
  }
  else
  {
    assert(user_autoexec == NULL);
  }

  /* Now the /C or /K option can be processed */
  if (p)
  {
    process_input(1, p);
    return spawnAndExit;
  }

  /* Don't place something here that must be executed after a /K or /C */

  if (showinfo)
  {
    short_version();
    putchar('\n');
    showcmds(NULL);
    putchar('\n');
  }

  return E_None;
}
Example #29
0
/*
 * Grab the filename of COMMAND.COM
 *
 *  If warn != 0, warnings can be issued; otherwise this functions
 *  is silent.
 */
void grabComFilename(int warn, char far *fnam)
{
  char *buf;
  size_t len;

  assert(fnam);

  /* Copy the filename into the local heap */
  len = _fstrlen(fnam);
  if(len >= INT_MAX || len < 1) {
    /* no filename specified */
    if(warn)
      error_syntax(NULL);
    return;
  }

  if((buf = malloc(len + 1)) == NULL) {
    if(warn) error_out_of_memory();
    return ;
  }
  _fmemcpy((char far*)buf, fnam, len);
  buf[len] = '\0';

    if (buf[1] != ':' || buf[2] != '\\')
    { char *p;

        /* expand the string for the user */
      p = dfnexpand(buf, NULL);
      free(buf);
      if((buf = p) == NULL) {
		  if(warn) error_out_of_memory();
		  return;
      }
      if(warn)
          error_init_fully_qualified(buf);
    }

    if(dfnstat(buf) & DFN_DIRECTORY) {
      /* The user specified a directory, try if we can find the
        COMMAND.COM with the standard name in there */
      char *p;

      if((p = realloc(buf, len + sizeof(COM_NAME) + 1)) == NULL) {
        if(warn) error_out_of_memory();
        free(buf);
        return;
      }
      buf = p;
      strcpy(&buf[len], "\\" COM_NAME);
    }

    if(!(dfnstat(buf) & DFN_FILE)) {
      /* not found */
      if(warn) error_open_file(buf);
      free(buf);
      return;
    }

  free(ComPath);    /* Save the found file */
  ComPath = buf;
}
Example #30
0
/*
 * do the prompt/input/process loop
 *
 *  If xflg is true, the function will not go interactive, but returns.
 *  If commandline != NULL, this command is processed first.
 *
 *  Return: 0: on success
 */
int process_input(int xflag, char *commandline)
{
    /* Dimensionate parsedline that no sprintf() can overflow the buffer
     */
  char parsedline[MAX_INTERNAL_COMMAND_SIZE + sizeof(errorlevel) * 8]
    , *readline;
/* Return the maximum pointer into parsedline to add 'numbytes' bytes */
#define parsedMax(numbytes)   \
  (parsedline + MAX_INTERNAL_COMMAND_SIZE - 1 - (numbytes))
  char *evar;
  char *tp;
  char *ip;
  char *cp;
  char forvar;
  int echothisline;
  int tracethisline;

  do
  {
  	interactive_command = 0;		/* not directly entered by user */
  	echothisline = tracethisline = 0;
    if(commandline) {
      ip = commandline;
      readline = commandline = NULL;
    } else {
    if ((readline = malloc(MAX_INTERNAL_COMMAND_SIZE + 1)) == NULL)
    {
      error_out_of_memory();
      return 1;
    }

      if (NULL == (ip = readbatchline(&echothisline, readline,
                      MAX_INTERNAL_COMMAND_SIZE)))
      { /* if no batch input then... */
      if (xflag   /* must not go interactive */
       || (fdattr(0) & 0x84) == 0x84  /* input is NUL device */
       || feof(stdin))    /* no further input */
      {
        free(readline);
        break;
      }

      /* Go Interactive */
		interactive_command = 1;		/* directly entered by user */
      readcommand(ip = readline, MAX_INTERNAL_COMMAND_SIZE);
      tracemode = 0;          /* reset trace mode */
      }
    }

    /* 
     * The question mark '?' has a double meaning:
     *	C:\> ?
     *		==> Display short help
     *
     *	C:\> ? command arguments
     *		==> enable tracemode for just this line
     */
    if(*(ip = trim(ip)) == '?') {
    	 ip = trim(ip + 1);
    	 if(!*ip) {		/* is short help command */
#ifdef INCLUDE_CMD_QUESTION
    	 	showcmds(ip);
#endif
			free(readline);
			continue;
		}
		/* this-line-tracemode */
		echothisline = 0;
		tracethisline = 1;
	}

  /* The FOR hack
    If the line matches /^\s*for\s+\%[a-z]\s/, the FOR hack
    becomes active, because FOR requires the sequence "%<ch>"
    in its input.
    When the percent (%) expansion is made later on, any
    sequence "%<ch>" is retained.
  */
  cp = ip;
  if(matchtok(cp, "for") && *cp == '%' && isalpha(cp[1])
   && isspace(cp[2]))   /* activate FOR hack */
    forvar = toupper(cp[1]);
  else forvar = 0;

  cp = parsedline;
    while (*ip)
    {
      /* Assume that at least one character is added, place the
        test here to simplify the switch() statement */
      if(cp >= parsedMax(1)) {
        cp = NULL;    /* error condition */
        break;
      }
      if (*ip == '%')
      {
        switch (*++ip)
        {
          case '\0':    /* FOR hack forvar == 0 if no FOR is active */
            *cp++ = '%';
            break;

          case '%':
            *cp++ = *ip++;
            break;

          case '0':
          case '1':
          case '2':
          case '3':
          case '4':
          case '5':
          case '6':
          case '7':
          case '8':
          case '9':
            if (NULL != (tp = find_arg(*ip - '0')))
            {
              if(cp >= parsedMax(strlen(tp))) {
                cp = NULL;
                goto intBufOver;
              }
              cp = stpcpy(cp, tp);
              ip++;
            }
            else
              *cp++ = '%';
              /* Let the digit be copied in the cycle */

            break;

          case '?':
            /* overflow check: parsedline has that many character
              "on reserve" */
            cp += sprintf(cp, "%u", errorlevel);
            ip++;
            break;

          default:
            if(forvar == toupper(*ip)) {    /* FOR hack */
              *cp++ = '%';			/* let the var be copied in next cycle */
              break;
            }
            if ((tp = strchr(ip, '%')) != NULL)
            {
              *tp = '\0';

              if ((evar = getEnv(ip)) != NULL) {
                if(cp >= parsedMax(strlen(evar))) {
                  cp = NULL;
                  goto intBufOver;
                }
                cp = stpcpy(cp, evar);
               }

              ip = tp + 1;
            }
            break;
        }
        continue;
      }

      if (iscntrl(*ip))
        *cp = ' ';
      else 
      	*cp++ = *ip++;
    }

intBufOver:
    free(readline);

  if(!cp) {     /* internal buffer overflow */
    error_line_too_long();
    continue;
  }

    *cp = '\0';   /* terminate copied string */

    if (echothisline)           /* Echo batch file line */
    {
      printprompt();
      puts(parsedline);
    }

    if (*parsedline)
    {
      if(tracethisline)
      	++tracemode;
      parsecommandline(parsedline);
      if(tracethisline)
      	--tracemode;
      if (echothisline || echo)
        putchar('\n');
    }
  }
  while (!canexit || !exitflag);

  return 0;
}