Ejemplo n.º 1
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;
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 3
0
int batch(char *fullname, char *firstword, char *param)
{
  /*
   * Start batch file execution
   *
   * The firstword parameter is the full filename of the batch file.
   */

   assert(fullname);
   assert(firstword);
   assert(param);

  if ((fullname = dfnexpand(fullname, 0)) == 0)
  {
    error_out_of_memory();
    return 1;
  }

  dprintf(("batch ('%s', '%s', '%s')\n", fullname, firstword,
           param));

  while (bc && bc->forvar)      /* Kill any and all FOR contexts */
    exit_batch();

  if (bc == 0)               /* No current batch file, create new context */
  {
    if (!newBatchContext()) {
    	free(fullname);
      return 1;
    }
  }
  else
  {                             /* Then we are transferring to another batch */
    struct bcontext *q;
    int echo;

    clearBatchContext(bc);

    q = bc->prev;               /* preserve context chain intact */
    echo = bc->echo;            /* preserve former ECHO state */
    /* if the _current_ ECHO state would be preserved,
       the following case would forget about the
       ECHO state on the interactive command line:
       === File BATCH1.BAT
       @echo off
       batch2
       === File BATCH2.BAT
       @echo off
       ===
       The transfer to BATCH2 would destroy BTACH1's
       context and therefore the original ECHO state.
       because BATCH2 is called with ECHO OFF, this
       state would be preserved as the command line's
       ECHO state */
    initBatchContext(bc);
    bc->prev = q;
    bc->echo = echo;
  }

  bc->bfnam = fullname;         /* already duplicated */
  if(0 == (bc->bfirst = strdup(firstword))
   || !setBatchParams(param)) {	 /* out of memory condition */
  	exit_batch();		/* clear this erroreous batch context */
  	return 1;
  }

  return 0;
}
Ejemplo n.º 4
0
int cmd_del(char *rest)
{
  int ec = E_None;    /* exit code */
  int i;
  unsigned count = 0;

  struct ffblk f;

  /* Make fullname somewhat larger to ensure that appending
     a matched name, one backslash and one hope. */
  char fullname[MAXPATH + sizeof(f.ff_name) + 2],
   *p, *q;
  int len;

  char **arg;
  int argc, optc;

  /* initialize options */
  optP = 0;

  if((arg = scanCmdline(rest, opt_del, 0, &argc, &optc)) == 0)
    return E_Other;

  if(!argc) {
      error_req_param_missing();
      ec = E_Useage;
     }
  else {
    i = 0;
    do {
      assert(arg[i]);

    /* Get the pattern fully-qualified */
    /* Note: An absolute path always contains:
       A:\\
       --> It's always three bytes long at minimum
       and always contains a backslash */
    p = dfnexpand(arg[i], 0);
    assert(strlen(p) >= 3);
    if ((len = strlen(p)) >= MAXPATH)
    {
      error_filename_too_long(p);
      free(p);
     ec = E_Other;
     goto errRet;
    }
    strcpy(fullname, p);        /* Operating over a local buffer simplifies
                     the process; rather than keep the pattern
                     within dynamic memory */
    free(p);
    p = fullname + len;

    /* check if it is a directory */
    if(dfnstat(fullname) & DFN_DIRECTORY)
    {
      if (p[-1] != '\\')
      *p++ = '\\';
    }

    if (p[-1] == '\\')    /* delete a whole directory */
      p = stpcpy(p, "*.*");

    /* p := address to copy the filename to to form the fully-qualified
     filename */
    /* There is at least one backslash within fullname, because of dfnexpand() */
    while (*--p != '\\') ;
    ++p;

    /* make sure user is sure if all files are to be
     * deleted */
    if (!optP && *p == '*' && ((q = strchr(p, '.')) == 0 || q[1] == '*'))
    {
    displayString(TEXT_MSG_DELETE_ALL);
    if (vcgetcstr("YN\n\r") != 'Y')
    {
      ec = E_Other;
      goto errRet;
    }
    }

    if (FINDFIRST(fullname, &f, FA_ARCH))
    {
    error_sfile_not_found(fullname);
    }
    else do {
    strcpy(p, f.ff_name);       /* Make the full path */

    if (optP)
    {
      printf("%s, Delete(Y/N)?", fullname);
      switch (vcgetcstr("YN\n\r"))
      {
      case '\3':             /* ^Break pressed */
        ec = E_CBreak;
        goto errRet;
      case 'Y':
        break;                /* yes, delete */
      default:
        continue;             /* no, don't delete */
      }
    }
    else if (cbreak) {           /* is also probed for in vcgetstr() */
        ec = E_CBreak;
      goto errRet;
    }

#ifdef NODEL
  /* define NODEL if you want to debug */
    puts(fullname);
#else
    if (unlink(fullname) != 0)
    {
      perror(fullname);   /* notify the user */
    }
    else ++count;
#endif

    } while (FINDNEXT(&f) == 0);
    } while(++i < argc);
  }

errRet:

    if(echo) {
      dispCount(count, "no file", "one file", "%u files");
      puts(" removed.");
    }

    freep(arg);
  return ec;
}
Ejemplo n.º 5
0
int cmd_copy(char *rest)
{ char **argv, *p;
  int argc, opts, argi;
  int freeDestFile = 0;
  struct CopySource *h;

  /* Initialize options */
  optA = optB = optV = optY = 0;

  /* read the parameters from env */
  if ((argv = scanCmdline(getEnv("COPYCMD"), opt_copy, 0, &argc, &opts))
   == 0)
    return 1;
  freep(argv);    /* ignore any parameter from env var */

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

  /* scan the trailing '/a' and '/b' options */
  while(argc > 0 && isoption(argv[argc - 1])) {
    p = argv[--argc];     /* argv[] must not be changed */
    if(leadOptions(&p, opt_copy1, 0) != E_None) {
      freep(argv);
      return 1;
    }
  }

  initContext();

  /* Now parse the remaining arguments into the copy file
    structure */
  for(argi = 0; argi < argc; ++argi)
    if(isoption(p = argv[argi])) {    /* infix /a or /b */
      if(leadOptions(&p, opt_copy1, 0) != E_None) {
        killContext();
        freep(argv);
        return 1;
      }
      /* Change the flags of the previous argument */
      if(lastApp)
        lastApp->flags = cpyFlags();
    } else {            /* real argument */
      if(*p == '+') {       /* to previous argument */
        appendToFile = 1;
        while(*++p == '+');
        if(!*p)
          continue;
      }

      if(!addSource(p)) {
        killContext();
        freep(argv);
        return 1;
      }

    }

  if(appendToFile) {
    error_trailing_plus();
    killContext();
    freep(argv);
    return 1;
  }

  if(!last) {   /* Nothing to do */
    error_nothing_to_do();
    killContext();
    freep(argv);
    return 1;
  }

  assert(head);

  /* Now test if a destination was specified */
  if(head != last && !last->app) {  /* Yeah */
    destFile = dfnexpand(last->fnam, 0);
    if(!destFile) {
      error_out_of_memory();
      goto errRet;
    }
    freeDestFile = 1;
    h = head;         /* remove it from argument list */
    while(h->nxt != last) {
      assert(h->nxt);
      h = h->nxt;
    }
    free(last);
    (last = h)->nxt = 0;
    p = strchr(destFile, '\0') - 1;
    if(*p == '\\' || *p == '/')		/* must be a directory */
    	destIsDir = 1;
    else destIsDir = dfnstat(destFile) & DFN_DIRECTORY;
  } else {              /* Nay */
    destFile = ".";
    destIsDir = 1;
  }

  /* Now copy the files */
  h = head;
  while(copyFiles(h) && (h = h->nxt) != 0);

  if(freeDestFile)
    free(destFile);
errRet:
  killContext();
  freep(argv);
  return 0;
}
Ejemplo n.º 6
0
/*
 *  Try to create a temporary file with the supplied path, also
 *  fully-qualify it
 *
 *  If ext != NULL, its contents is appended to a randomized prefix,
 *  most useful, if 'ext' begins with a dot, to give the file to be
 *  created an extension.
 */
char *mktempfile(const char * const path, const char *ext)
{
  char *fn, *newpath;
  int cnt,
    fd;

  if (!path)                    /* to simplify the caller function */
    return 0;

  if ((fn = dfnexpand(path, 0)) == 0)
  {                             /* out-of-mem */
    nomem();
    return 0;
  }

  if (!ext)                     /* make sure it's a legal string */
    ext = "";

  /* The completed name consits of:
     + the absolute path name,
     + the '\\' path component delimited path vs. filename
     + eight (8) characters randomized filename
     + the user-supplied extension
     + the '\0' terminator byte
   */
  if ((newpath = realloc(fn, strlen(fn) + strlen(ext) + 10)) == 0)
  {
    /* out of mem */
    free(fn);
    nomem();
    return 0;
  }

  fn = strchr(newpath, '\0');      /* where the '\\' is to be */
  if (fn[-1] != '\\')           /* maybe 1 byte is wasted here */
    *fn++ = '\\';

  cnt = 0;
  do {             /* randomize filename and probe if it can be created */
    /* OK, this is not that efficient, but easy to implement
       right now -- 1998/10/27 ska */
    sprintf(fn, "CMD%x%s", cnt, ext);
    if (!++cnt)                 /* overflow */
      goto errRet;

    /* loop until either the open succeeded or failed with
       something different then "file already exists"

       However, this failed in Win98 DOSbox on root of
       CD-Rom drive:
       (fd = open(path, O_CREAT | O_EXCL | O_WRONLY
       , S_IREAD | S_IWRITE)) == -1 && errno == EACCES);

       Because DOS returned: EACCES

       Let's assume access() does not fail on directories:
     */
  }
  while(dfnstat(newpath)); /* such entry already exists */

  /* Make semaphore test */
  fd = open(newpath, O_CREAT | O_EXCL | O_WRONLY, S_IREAD | S_IWRITE);
  if (fd != -1)
  {                             /* success */
    close(fd);
    return newpath;
  }

errRet:
  free(newpath);
  return 0;
}
Ejemplo n.º 7
0
char *dfnfullpath(const char * const fnam)
{	char *fullpath;
	char *paths;
	char *q;				/* intermediate pointers */
	char *nxtDelim;
	int cnt;

#ifdef OS_WIN32
#ifdef SUPPORT_UNC_PATH
	DBG_ENTER("dfnufullpath2", Suppl_dfn)
#else
	DBG_ENTER("dfnfullpath2", Suppl_dfn)
#endif
#else
#ifdef SUPPORT_UNC_PATH
	DBG_ENTER("dfnufullpath", Suppl_dfn)
#else
	DBG_ENTER("dfnfullpath", Suppl_dfn)
#endif
#endif

	assert(fnam);

	DBG_ARGUMENTS( ("fnam=\"%s\"", fnam) )

	chkHeap
	if((fullpath = dfnexpand(fnam, 0)) == 0)
		DBG_RETURN_S( 0)

	assert(*fullpath);

#ifdef SUPPORT_UNC_PATH
	if(isUNCpath(fullpath)) paths = UNCpath(fullpath);
	else
#endif
	{
		assert(*fullpath && fullpath[1] == ':');
		paths = &fullpath[2];
	}

	chkHeap
	assert(*paths == '\\');
	q = paths;
	while(*q == '\\' && *++q) {
		/* Check for special directories */
		if((nxtDelim = strchr(q, '\\')) == 0)
			nxtDelim = strchr(q, '\0');
		if((cnt = strspn(q, ".")) == nxtDelim - q
#ifndef FEATURE_LONG_FILENAMES
		 && cnt < 3		/* DOS limits to "." and ".." */
#endif
		) {
			/* all dots --> special directory */
			/* Relocate "q" (cnt-1) path components to the left */
			while(--q > paths && --cnt) {
				/* search next '\' to the left */
				while(*--q != '\\');
				++q;
			}
			if(*nxtDelim) {
				/* some components left, move them up */
				/* Note: *nxtDelim == *q == '\\', but by copying over
					this single character one needs not implement a
					special handling if nxtDelim[1] == '\0' */
				memmove(q, nxtDelim, strlen(nxtDelim) + 1);
			} else {
				/* this was the last component, but because this was
					a special directory, the information must be preserved
					that it is a directory --> append trailing backslash */
				q[1] = '\0';
			}
		} else {
			q = nxtDelim;
		}
	}

	chkHeap
	DBG_RETURN_S( StrTrim(fullpath))
}