Пример #1
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);
}
Пример #2
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;
}
Пример #3
0
int dfnfreplace(const char * const newname, const char * const oldname)
{	char *bak;

	DBG_ENTER("dfnfreplace", Suppl_dfn)

	assert(newname);
	assert(oldname);

	DBG_ARGUMENTS( ("to:\"%s\", from=\"%s\"", newname, oldname) )

	chkHeap
	if((bak = dfnbakname(newname)) != 0) {
		DBG_INFO( ("bakup=\"%s\"", bak) )
		unlink(bak);		/* delete the backup file, if present */
		rename(newname, bak);	/* backup current file, if present */
		chkHeap
		free(bak);
		chkHeap
		if(!dfnstat(newname)) {
			/* file doesn't exist (either renamed or not present at all) */
			rename(oldname, newname);
			if(dfnstat(newname))	/* rename succeded */
				DBG_RETURN_I( ESUPPL_OK)
		}
Пример #4
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;
}
Пример #5
0
int grabComFilename(const int warn, const char far * const fnam)
{
    char *buf;
    size_t len;
    int rc;

    dprintf( ("[INIT: grabComFilename(%s)]\n", fnam) );
    if(!fnam)
        return 4;

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

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

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

        /* expand the string for the user */
        p = abspath(buf, warn);
        free(buf);
        if((buf = p) == 0)
            return 4;
        if(warn)
            error_init_fully_qualified(buf);

        len = strlen(buf);
    }

    while(buf[len - 1] == '\\')
        --len;
    buf[len] = 0;

    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)) == 0) {
            if(warn) error_out_of_memory();
            free(buf);
            return 4;
        }
        buf = p;
        strcpy(&buf[len], "\\" COM_NAME);
    }


    if(0 != (rc = validResFile(buf))) {
        if(warn) switch(rc) {
            default:
#ifdef NDEBUG
                assert(0);
#endif
            case 1:
                error_open_file(buf);
                break;
            case 2:
                error_fcom_is_device(buf);
                break;
            case 3:
                error_fcom_invalid(buf);
                break;
            }

        free(buf);
        return rc;
    }

    free(ComPath);    /* Save the found file */
    ComPath = buf;
    dprintf(("[INIT: new resource file name: %s]\n", ComPath));

    isSwapFile = 0;
    buf = dfnfilename(ComPath);
    assert(buf);
    if((buf = strchr(buf, '.')) != 0
            && stricmp(buf, ".swp") == 0) {
        dprintf(("[INIT: VSpawn file found: %s]\n", ComPath));
        memcpy(++buf, "COM", 3);
        isSwapFile = buf - ComPath;
    }

    return 0;
}
Пример #6
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;
}
Пример #7
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;
}
Пример #8
0
int cd_dir(char *param, int cdd, const char * const fctname)
{	char **argv, *dir;
	int argc, opts;
	int rv, freeDir;

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

	freeDir = 0;
	rv = 1;

	/* if doing a CD and no parameters given, print out current directory */
	if(argc == 0) {
		if((dir = cwd(0)) != 0) {
			puts(dir);
			freeDir = 1;
			goto okRet;
		}
		goto errRet;
	} else if(argc != 1) {
		error_syntax(0);
		goto errRet;
	}
	else {
		assert(argv[0]);

#ifdef FEATURE_CDD_FNAME
		/* if path refers to an existing file and not directory, ignore filename portion */
            if (cdd && (dfnstat(argv[0]) & DFN_FILE))
		{
			dir = strrchr(argv[0], '\\');
			if (dir == NULL)
			{
				dir = argv[0];
				if (dir[1] == ':') dir[2]='\0';  /* change drive only, no path */
				else goto okRet;                 /* no drive, no path, so exit early */
			}
			else /* includes a path or refers to root dir */
			{
				*(dir+1) = '\0';
			}
		}
#endif

		dir = strchr(argv[0], '\0');
		/* take off trailing \ if any, but ONLY if dir is not the root dir */
		while(dir > &argv[0][1] && *--dir == '\\' && dir[-1] != ':')
			*dir = '\0';

		dir = argv[0];

#ifdef FEATURE_LAST_DIR
		if(strcmp(dir, "-") == 0) {
			assert(!freeDir);
			/* change to last directory */
			lastDirGet(&dir);
			freeDir = 1;
		}

		lastDirSet();
		if(!dir) 	/* "CD -" without a CD before at all */
			goto okRet;
#endif
		if(*dir && dir[1] == ':') {
			if(cdd) {
				if(changeDrive(*dir) != 0)
					goto errRet;
				if(!dir[2])		/* only change drive */
					goto okRet;
			} else if(!dir[2]) {	/* Real CHDIR displays CWD of
										specified drive */
				assert(freeDir == 0);

				if((dir = cwd(*dir)) != 0) {
					puts(dir);
					freeDir = 1;
					goto okRet;
				}
				goto errRet;
			}
		}
		dprintf(("%s: '%s'\n", fctname, dir));
		if(chdir(dir) != 0) {
			error_dirfct_failed(fctname, dir);
			goto errRet;
		}
	}

okRet:
	rv = 0;
errRet:
	freep(argv);
	if(freeDir)
		free(dir);
	return rv;
}
Пример #9
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;
}