示例#1
0
文件: path.c 项目: DJEX93/dsploit
/*
 * join_path_components - join two path components, inserting a slash
 *
 * We omit the slash if either given component is empty.
 *
 * ret_path is the output area (must be of size MAXPGPATH)
 *
 * ret_path can be the same as head, but not the same as tail.
 */
void
join_path_components(char *ret_path,
					 const char *head, const char *tail)
{
	if (ret_path != head)
		strlcpy(ret_path, head, MAXPGPATH);

	/*
	 * Remove any leading "." in the tail component.
	 *
	 * Note: we used to try to remove ".." as well, but that's tricky to get
	 * right; now we just leave it to be done by canonicalize_path() later.
	 */
	while (tail[0] == '.' && IS_DIR_SEP(tail[1]))
		tail += 2;

	if (*tail)
	{
		/* only separate with slash if head wasn't empty */
		snprintf(ret_path + strlen(ret_path), MAXPGPATH - strlen(ret_path),
				 "%s%s",
				 (*(skip_drive(head)) != '\0') ? "/" : "",
				 tail);
	}
}
int target_lookup(MainParam_t *mp, const char *arg)
{
	if((mp->lookupflags & NO_UNIX) || skip_drive(arg) > arg)
		return dos_target_lookup(mp, arg);
	else
		return unix_target_lookup(mp, arg);
}
示例#3
0
/*
 * Extracts the actual name of the program as called - 
 * stripped of .exe suffix if any
 */
const char *
get_progname(const char *argv0)
{
	const char *nodir_name;

	nodir_name = last_dir_separator(argv0);
	if (nodir_name)
		nodir_name++;
	else
		nodir_name = skip_drive(argv0);

#if defined(__CYGWIN__) || defined(WIN32)
	/* strip .exe suffix, regardless of case */
	if (strlen(nodir_name) > sizeof(EXE) - 1 &&
		pg_strcasecmp(nodir_name + strlen(nodir_name)-(sizeof(EXE)-1), EXE) == 0)
	{
		char *progname;

		progname = strdup(nodir_name);
		if (progname == NULL)
		{
			fprintf(stderr, "%s: out of memory\n", nodir_name);
			exit(1);	/* This could exit the postmaster */
		}
		progname[strlen(progname) - (sizeof(EXE) - 1)] = '\0';
		nodir_name = progname; 
	}
#endif

	return nodir_name;
}
示例#4
0
文件: path.c 项目: DJEX93/dsploit
/*
 * Extracts the actual name of the program as called -
 * stripped of .exe suffix if any
 */
const char *
get_progname(const char *argv0)
{
	const char *nodir_name;
	char	   *progname;

	nodir_name = last_dir_separator(argv0);
	if (nodir_name)
		nodir_name++;
	else
		nodir_name = skip_drive(argv0);

	/*
	 * Make a copy in case argv[0] is modified by ps_status. Leaks memory, but
	 * called only once.
	 */
	progname = strdup(nodir_name);
	if (progname == NULL)
	{
		fprintf(stderr, "%s: out of memory\n", nodir_name);
		exit(1);				/* This could exit the postmaster */
	}

#if defined(__CYGWIN__) || defined(WIN32)
	/* strip ".exe" suffix, regardless of case */
	if (strlen(progname) > sizeof(EXE) - 1 &&
	pg_strcasecmp(progname + strlen(progname) - (sizeof(EXE) - 1), EXE) == 0)
		progname[strlen(progname) - (sizeof(EXE) - 1)] = '\0';
#endif

	return progname;
}
示例#5
0
/* Returns a malloced string */
char *SLpath_pathname_sans_extname (SLFUTURE_CONST char *drivefile)
{
   char *b;
   char *file;

   drivefile = SLmake_string (drivefile);
   if (drivefile == NULL)
     return NULL;

   file = (char *)skip_drive (drivefile);
   b = file + strlen (file);

   while (b != file)
     {
	b--;
	if (IS_PATH_SEP(*b))
	  break;

	if (*b == '.')
	  {
	     *b = 0;
	     break;
	  }
     }

   return drivefile;
}
示例#6
0
文件: path.c 项目: DJEX93/dsploit
/*
 *	first_dir_separator
 *
 * Find the location of the first directory separator, return
 * NULL if not found.
 */
char *
first_dir_separator(const char *filename)
{
	const char *p;

	for (p = skip_drive(filename); *p; p++)
		if (IS_DIR_SEP(*p))
			return (char *) p;
	return NULL;
}
示例#7
0
文件: path.c 项目: DJEX93/dsploit
/*
 *	trim_trailing_separator
 *
 * trim off trailing slashes, but not a leading slash
 */
static void
trim_trailing_separator(char *path)
{
	char	   *p;

	path = skip_drive(path);
	p = path + strlen(path);
	if (p > path)
		for (p--; p > path && IS_DIR_SEP(*p); p--)
			*p = '\0';
}
示例#8
0
文件: path.c 项目: DJEX93/dsploit
/*
 *	last_dir_separator
 *
 * Find the location of the last directory separator, return
 * NULL if not found.
 */
char *
last_dir_separator(const char *filename)
{
	const char *p,
			   *ret = NULL;

	for (p = skip_drive(filename); *p; p++)
		if (IS_DIR_SEP(*p))
			ret = p;
	return (char *) ret;
}
static int common_dos_loop(MainParam_t *mp, const char *pathname,
			   lookupState_t *lookupState, int open_mode)

{
	Stream_t *RootDir;
	char *cwd;
	char *drive;
	char *rest;

	int ret;
	mp->loop = _dos_loop;
	
	drive='\0';
	cwd = "";
	if((rest = skip_drive(pathname)) > pathname) {
		drive = get_drive(pathname, NULL);
		if (strncmp(pathname, mp->mcwd, rest - pathname) == 0)
			cwd = skip_drive(mp->mcwd);
		pathname = rest;
	} else {
		drive = get_drive(mp->mcwd, NULL);
		cwd = skip_drive(mp->mcwd);
	}

	if(*pathname=='/') /* absolute path name */
		cwd = "";

	RootDir = mp->File = open_root_dir(drive, open_mode);
	if(!mp->File)
		return ERROR_ONE;

	ret = recurs_dos_loop(mp, cwd, pathname, lookupState);
	if(ret & NO_CWD) {
		/* no CWD */
		*mp->mcwd = '\0';
		unlink_mcwd();
		ret = recurs_dos_loop(mp, "", pathname, lookupState);
	}
	FREE(&RootDir);
	return ret;
}
示例#10
0
int SLpath_is_absolute_path (SLFUTURE_CONST char *name)
{
   if (name == NULL)
     return -1;

#ifdef UNIX_PATHNAMES_OK
   return (*name == '/');
#else
   if (IS_PATH_SEP (*name))
     return 1;

   /* If it contains a drive specifier, regard it as absolute */
   if (name != skip_drive (name))
     return 1;

   return 0;
#endif
}
示例#11
0
/* If file is /a/b/c/basename, this function returns a pointer to basename */
SLFUTURE_CONST char *SLpath_basename (SLFUTURE_CONST char *drivefile)
{
   SLFUTURE_CONST char *b, *file;

   if (drivefile == NULL) return NULL;

   file = skip_drive (drivefile);
   b = file + strlen (file);

   while (b != file)
     {
	b--;
	if (IS_PATH_SEP(*b))
	  return b + 1;
     }

   return b;
}
示例#12
0
int main_loop(MainParam_t *mp, char **argv, int argc)
{
	int i;
	int ret, Bret;
	
	Bret = 0;

	if(argc != 1 && mp->targetName) {
		fprintf(stderr,
			"Several file names given, but last argument (%s) not a directory\n", mp->targetName);
	}

	for (i = 0; i < argc; i++) {
		if ( got_signal )
			break;
		mp->originalArg = argv[i];
		mp->basenameHasWildcard = strpbrk(_basename(mp->originalArg), 
						  "*[?") != 0;
		if (mp->unixcallback && skip_drive(argv[i]) == argv[i])
			ret = unix_loop(0, mp, argv[i], 1);
		else
			ret = dos_loop(mp, argv[i]);
		
		if (! (ret & (GOT_ONE | ERROR_ONE)) ) {
			/* one argument was unmatched */
			fprintf(stderr, "%s: File \"%s\" not found\n",
				progname, argv[i]);
			ret |= ERROR_ONE;
		}
		Bret |= ret;
		if(mp->fast_quit && (Bret & (MISSED_ONE | ERROR_ONE)))
			break;
	}
	FREE(&mp->targetDir);
	if(Bret & ERROR_ONE)
		return 1;
	if ((Bret & GOT_ONE) && ( Bret & MISSED_ONE))
		return 2;
	if (Bret & MISSED_ONE)
		return 1;
	return 0;
}
示例#13
0
文件: path.c 项目: DJEX93/dsploit
/*
 * Detect whether a path contains any parent-directory references ("..")
 *
 * The input *must* have been put through canonicalize_path previously.
 *
 * This is a bit tricky because we mustn't be fooled by "..a.." (legal)
 * nor "C:.." (legal on Unix but not Windows).
 */
bool
path_contains_parent_reference(const char *path)
{
	int			path_len;

	path = skip_drive(path);	/* C: shouldn't affect our conclusion */

	path_len = strlen(path);

	/*
	 * ".." could be the whole path; otherwise, if it's present it must be at
	 * the beginning, in the middle, or at the end.
	 */
	if (strcmp(path, "..") == 0 ||
		strncmp(path, "../", 3) == 0 ||
		strstr(path, "/../") != NULL ||
		(path_len >= 3 && strcmp(path + path_len - 3, "/..") == 0))
		return true;

	return false;
}
示例#14
0
文件: path.c 项目: DJEX93/dsploit
/*
 *	trim_directory
 *
 *	Trim trailing directory from path, that is, remove any trailing slashes,
 *	the last pathname component, and the slash just ahead of it --- but never
 *	remove a leading slash.
 */
static void
trim_directory(char *path)
{
	char	   *p;

	path = skip_drive(path);

	if (path[0] == '\0')
		return;

	/* back up over trailing slash(es) */
	for (p = path + strlen(path) - 1; IS_DIR_SEP(*p) && p > path; p--)
		;
	/* back up over directory name */
	for (; !IS_DIR_SEP(*p) && p > path; p--)
		;
	/* if multiple slashes before directory name, remove 'em all */
	for (; p > path && IS_DIR_SEP(*(p - 1)); p--)
		;
	/* don't erase a leading slash */
	if (p == path && IS_DIR_SEP(*p))
		p++;
	*p = '\0';
}
示例#15
0
文件: path.c 项目: DJEX93/dsploit
/*
 *	Clean up path by:
 *		o  make Win32 path use Unix slashes
 *		o  remove trailing quote on Win32
 *		o  remove trailing slash
 *		o  remove duplicate adjacent separators
 *		o  remove trailing '.'
 *		o  process trailing '..' ourselves
 */
void
canonicalize_path(char *path)
{
	char	   *p,
			   *to_p;
	char	   *spath;
	bool		was_sep = false;
	int			pending_strips;

#ifdef WIN32

	/*
	 * The Windows command processor will accept suitably quoted paths with
	 * forward slashes, but barfs badly with mixed forward and back slashes.
	 */
	for (p = path; *p; p++)
	{
		if (*p == '\\')
			*p = '/';
	}

	/*
	 * In Win32, if you do: prog.exe "a b" "\c\d\" the system will pass \c\d"
	 * as argv[2], so trim off trailing quote.
	 */
	if (p > path && *(p - 1) == '"')
		*(p - 1) = '/';
#endif

	/*
	 * Removing the trailing slash on a path means we never get ugly double
	 * trailing slashes. Also, Win32 can't stat() a directory with a trailing
	 * slash. Don't remove a leading slash, though.
	 */
	trim_trailing_separator(path);

	/*
	 * Remove duplicate adjacent separators
	 */
	p = path;
#ifdef WIN32
	/* Don't remove leading double-slash on Win32 */
	if (*p)
		p++;
#endif
	to_p = p;
	for (; *p; p++, to_p++)
	{
		/* Handle many adjacent slashes, like "/a///b" */
		while (*p == '/' && was_sep)
			p++;
		if (to_p != p)
			*to_p = *p;
		was_sep = (*p == '/');
	}
	*to_p = '\0';

	/*
	 * Remove any trailing uses of "." and process ".." ourselves
	 *
	 * Note that "/../.." should reduce to just "/", while "../.." has to be
	 * kept as-is.	In the latter case we put back mistakenly trimmed ".."
	 * components below.  Also note that we want a Windows drive spec to be
	 * visible to trim_directory(), but it's not part of the logic that's
	 * looking at the name components; hence distinction between path and
	 * spath.
	 */
	spath = skip_drive(path);
	pending_strips = 0;
	for (;;)
	{
		int			len = strlen(spath);

		if (len >= 2 && strcmp(spath + len - 2, "/.") == 0)
			trim_directory(path);
		else if (strcmp(spath, ".") == 0)
		{
			/* Want to leave "." alone, but "./.." has to become ".." */
			if (pending_strips > 0)
				*spath = '\0';
			break;
		}
		else if ((len >= 3 && strcmp(spath + len - 3, "/..") == 0) ||
				 strcmp(spath, "..") == 0)
		{
			trim_directory(path);
			pending_strips++;
		}
		else if (pending_strips > 0 && *spath != '\0')
		{
			/* trim a regular directory name canceled by ".." */
			trim_directory(path);
			pending_strips--;
			/* foo/.. should become ".", not empty */
			if (*spath == '\0')
				strcpy(spath, ".");
		}
		else
			break;
	}

	if (pending_strips > 0)
	{
		/*
		 * We could only get here if path is now totally empty (other than a
		 * possible drive specifier on Windows). We have to put back one or
		 * more ".."'s that we took off.
		 */
		while (--pending_strips > 0)
			strcat(path, "../");
		strcat(path, "..");
	}
}
示例#16
0
void mcat(int argc, char **argv, int type)
{
    struct device *dev;
    struct device out_dev;
    char *drive, name[EXPAND_BUF];
    char errmsg[200];
    Stream_t *Stream;
    char buf[BUF_SIZE];

    mt_off_t address = 0;

    char mode = O_RDONLY;
    int optindex = 1;
    size_t len;

    noPrivileges = 1;

    if (argc < 2) {
        usage();
    }

    if (argv[1][0] == '-') {
        if (argv[1][1] != 'w') {
            usage();
        }
        mode = O_WRONLY;
        optindex++;
    }

    if (argc - optindex < 1)
        usage();


    if (skip_drive(argv[optindex]) == argv[optindex])
        usage();

    drive = get_drive(argv[optindex], NULL);

    /* check out a drive whose letter and parameters match */
    sprintf(errmsg, "Drive '%s:' not supported", drive);
    Stream = NULL;
    for (dev=devices; dev->name; dev++) {
        FREE(&Stream);
        if (strcmp(dev->drive, drive) != 0)
            continue;
        out_dev = *dev;
        expand(dev->name,name);
#ifdef USING_NEW_VOLD
        strcpy(name, getVoldName(dev, name));
#endif

        Stream = 0;
#ifdef USE_XDF
        Stream = XdfOpen(&out_dev, name, mode, errmsg, 0);
        if(Stream)
            out_dev.use_2m = 0x7f;

#endif

#ifdef USE_FLOPPYD
        if(!Stream)
            Stream = FloppydOpen(&out_dev, dev, name,
                                 mode, errmsg, 0, 1);
#endif


        if (!Stream)
            Stream = SimpleFileOpen(&out_dev, dev, name, mode,
                                    errmsg, 0, 1, 0);

        if( !Stream)
            continue;
        break;
    }

    /* print error msg if needed */
    if ( dev->drive == 0 ) {
        FREE(&Stream);
        fprintf(stderr,"%s\n",errmsg);
        exit(1);
    }

    if (mode == O_WRONLY) {
        while ((len = fread(buf, 1, BUF_SIZE, stdin))
                == BUF_SIZE) {
            WRITES(Stream, buf, address, BUF_SIZE);
            address += BUF_SIZE;
        }
        if (len)
            WRITES(Stream, buf, address, len);
    } else {
        while ((len = READS(Stream, buf, address, BUF_SIZE))
                == BUF_SIZE) {
            fwrite(buf, 1, BUF_SIZE, stdout);
            address += BUF_SIZE;
        }
        if (len)
            fwrite(buf, 1, len, stdout);
    }

    FREE(&Stream);
    exit(0);
}
示例#17
0
/*
 *	has_drive_prefix
 *
 * Return true if the given pathname has a drive prefix.
 */
bool
has_drive_prefix(const char *path)
{
	return skip_drive(path) != path;
}
示例#18
0
/*
 * struct fs32_chdir_parms {
 *     unsigned short      iCurDirEnd;
 *     PTR16               pDir;
 *     PTR16               pcdfsd;
 *     PTR16               pcdfsi;
 *     unsigned short      flag;
 * };
 */
int FS32ENTRY fs32_chdir(struct fs32_chdir_parms *parms)
{
    char *pDir;
    struct cdfsi32 *pcdfsi;
    union cdfsd32 *pcdfsd;
    int rc;
    struct file *p_file;
    struct super_block *sb;
    int valid;
    char *tmp;
    struct inode *base;

    switch (parms->flag)
    {
        case CD_EXPLICIT:
            pcdfsi = VDHQueryLin(parms->pcdfsi);
            pcdfsd = VDHQueryLin(parms->pcdfsd);
            pDir = VDHQueryLin(parms->pDir);

            if (trace_FS_CHDIR)
            {
                kernel_printf("FS_CHDIR( CD_EXPLICIT, %s )", pDir);
            }

            rc = ERROR_INVALID_PARAMETER;
            if (parms->iCurDirEnd != CURDIREND_INVALID)
            {
                tmp = pDir + parms->iCurDirEnd;
                if ((pcdfsd->u.p_file) && (pcdfsd->u.p_file->f_magic == FILE_MAGIC))
                {
                    base = pcdfsd->u.p_file->f_inode;
                    if (base)
                    {
                        rc = NO_ERROR;
                    }
                }
            }
            else
            {
                sb = getvolume(pcdfsi->cdi_hVPB);
                if ((sb) && (sb->s_magic_internal == SUPER_MAGIC))
                {
                    tmp = skip_drive(pDir);
                    base = sb->s_mounted;
                    if (base)
                    {
                        rc = NO_ERROR;
                    }
                }
            }

            if (rc == NO_ERROR)
            {
                if ((p_file = open_by_name(base, tmp, OPENMODE_READONLY)) == 0)
                {
                    rc = ERROR_PATH_NOT_FOUND;
                }
                else
                {
                    if (!S_ISDIR(p_file->f_inode->i_mode))
                    {
                        kernel_printf("FS_CHDIR( %s ) Not a directory", pDir);
                        vfs_close(p_file);
                        rc = ERROR_ACCESS_DENIED;
                    }
                    else
                    {
                        pcdfsd->u.is_valid = 1;
                        pcdfsd->u.p_file = p_file;
                        rc = NO_ERROR;
                    }
                }
            }
            break;

        case CD_VERIFY:
            pcdfsi = VDHQueryLin(parms->pcdfsi);
            pcdfsd = VDHQueryLin(parms->pcdfsd);

            if (trace_FS_CHDIR)
            {
                kernel_printf("FS_CHDIR : flag = CD_VERIFY hVPB=0x%04X", pcdfsi->cdi_hVPB);
            }

            //
            // Gets the superblock from pcdfsi
            //
            sb = getvolume(pcdfsi->cdi_hVPB);
            valid = 1;
            if ((p_file = open_by_name(sb->s_mounted, skip_drive(pcdfsi->cdi_curdir), OPENMODE_READONLY)) == 0)
            {
                valid = 0;
            }
            else
            {
                if (!S_ISDIR(p_file->f_inode->i_mode))
                {
                    vfs_close(p_file);
                    valid = 0;
                }

                if (pcdfsi->cdi_flags & CDI_ISVALID)
                {
                    vfs_close(pcdfsd->u.p_file);
                }
                if (valid)
                {
                    pcdfsd->u.is_valid = 1;
                    pcdfsd->u.p_file = p_file;
                    return NO_ERROR;
                }
                else
                {
                    vfs_close(p_file);
                    return ERROR_PATH_NOT_FOUND;
                }
            }
            break;

        case CD_FREE:
            pcdfsd = VDHQueryLin(parms->pcdfsd);

            if (trace_FS_CHDIR)
            {
                kernel_printf("FS_CHDIR( CD_FREE )");
            }


            if (pcdfsd->u.is_valid == 1)
            {
                pcdfsd->u.is_valid = 0;
                if ((rc = vfs_close(pcdfsd->u.p_file)) != NO_ERROR)
                {
                    fs_err(FUNC_FS_CHDIR, FUNC_CLOSE, rc, THISFILE, __LINE__);
                }
//                return rc;
            }
            else
            {
                rc = NO_ERROR;
            }
            break;

        default:
            fs_log("FS_CHDIR : invalid flag");
            rc = ERROR_INVALID_PARAMETER;

    }

    return rc;
}
示例#19
0
int _mwrite_one(Stream_t *Dir,
		char *argname,
		char *shortname,
		write_data_callback *cb,
		void *arg,
		ClashHandling_t *ch)
{
	char longname[VBUFSIZE];
	const char *dstname;
	char dosname[13];
	int expanded;
	struct scan_state scan;
	clash_action ret;

	expanded = 0;

	if(isSpecial(argname)) {
		fprintf(stderr, "Cannot create entry named . or ..\n");
		return -1;
	}

	if(ch->name_converter == dos_name) {
		if(shortname)
			stripspaces(shortname);
		if(argname)
			stripspaces(argname);
	}

	if(shortname){
		ch->name_converter(shortname,0, &ch->use_longname, dosname);
		if(ch->use_longname & 1){
			/* short name mangled, treat it as a long name */
			argname = shortname;
			shortname = 0;
		}
	}
						
	/* Skip drive letter */
	dstname = skip_drive(argname);

	/* Copy original argument dstname to working value longname */
	strncpy(longname, dstname, VBUFSIZE-1);

	if(shortname) {
		ch->name_converter(shortname,0, &ch->use_longname, dosname);
		if(strcmp(shortname, longname))
			ch->use_longname |= 1;
	} else
		ch->name_converter(longname,0, &ch->use_longname, dosname);

	ch->action[0] = ch->namematch_default[0];
	ch->action[1] = ch->namematch_default[1];

	while (1) {
		switch((ret=get_slots(Dir, dosname, longname,
				      &scan, ch))){
			case NAMEMATCH_ERROR:
				return -1;	/* Non-file-specific error, 
						 * quit */
				
			case NAMEMATCH_SKIP:
				return -1;	/* Skip file (user request or 
						 * error) */

			case NAMEMATCH_PRENAME:
				ch->name_converter(longname,0,
						   &ch->use_longname, dosname);
				continue;
			case NAMEMATCH_RENAME:
				continue;	/* Renamed file, loop again */

			case NAMEMATCH_GREW:
				/* No collision, and not enough slots.
				 * Try to grow the directory
				 */
				if (expanded) {	/* Already tried this 
						 * once, no good */
					fprintf(stderr, 
						"%s: No directory slots\n",
						progname);
					return -1;
				}
				expanded = 1;
				
				if (dir_grow(Dir, scan.max_entry))
					return -1;
				continue;
			case NAMEMATCH_OVERWRITE:
			case NAMEMATCH_SUCCESS:
				return write_slots(Dir, dosname, longname,
						   &scan, cb, arg,
						   ch->use_longname);
			default:
				fprintf(stderr,
					"Internal error: clash_action=%d\n",
					ret);
				return -1;
		}

	}
}
示例#20
0
/*
 * struct fs32_opencreate_parms {
 *     PTR16          pfgenflag;
 *     PTR16          pEABuf;
 *     unsigned short attr;
 *     PTR16          pAction;
 *     unsigned short openflag;
 *     unsigned long  openmode;
 *     PTR16          psffsd;
 *     PTR16          psffsi;
 *     unsigned short iCurDirEnd;
 *     PTR16          pName;
 *     PTR16          pcdfsd;
 *     PTR16          pcdfsi;
 * };
 */
int FS32ENTRY fs32_opencreate(struct fs32_opencreate_parms *parms)
{
    char *pName;
    struct cdfsi32 *pcdfsi;
    union cdfsd32 *pcdfsd;
    struct sffsi32 *psffsi;
    union sffsd32 *psffsd;
    unsigned short *pAction;
    int rc;
    struct super_block *sb;
    struct file *p_file, *dir;
    UINT32 openmode, DOSmode;
    UINT32 accessmode;
    UINT16 newflag, existflag;
    char component[CCHMAXPATH];
    char parent[CCHMAXPATH];
    struct inode *inode;
    struct inode *inode_parent;
    struct inode *base;
    char *tmp;
    ino_t ino_no;

    psffsi = VDHQueryLin(parms->psffsi);
    psffsd = VDHQueryLin(parms->psffsd);
    if (parms->pcdfsi.seg)
        pcdfsi = VDHQueryLin(parms->pcdfsi);
    else
        pcdfsi = 0;
    if (parms->pcdfsd.seg)
        pcdfsd = VDHQueryLin(parms->pcdfsd);
    else
        pcdfsd = 0;
    pName = VDHQueryLin(parms->pName);
    pAction = VDHQueryLin(parms->pAction);

    if (trace_FS_OPENCREATE)
    {
        kernel_printf("FS_OPENCREATE(%s)", pName);
    }


#ifdef FS_TRACE
    if (parms->ulOpenMode & OPEN_FLAGS_DASD)
    {
        fs_log("OPEN_FLAGS_DASD");
    }


    if (parms->ulOpenMode & OPEN_FLAGS_WRITE_THROUGH)
    {
        fs_log("OPEN_FLAGS_WRITE_THROUGH");
    }
    if (parms->ulOpenMode & OPEN_FLAGS_FAIL_ON_ERROR)
    {
        fs_log("OPEN_FLAGS_FAIL_ON_ERROR");
    }
    if (parms->ulOpenMode & OPEN_FLAGS_NO_CACHE)
    {
        fs_log("OPEN_FLAGS_NO_CACHE");
    }
    if (parms->ulOpenMode & OPEN_FLAGS_NOINHERIT)
    {
        fs_log("OPEN_FLAGS_NO_INHERIT");
    }
#endif
    accessmode = parms->ulOpenMode & OPEN_ACCESS_MASK;

    if (accessmode == OPEN_ACCESS_READONLY)
    {
#ifdef FS_TRACE
        fs_log("OPEN_ACCESS_READONLY");
#endif
        openmode = OPENMODE_READONLY;
    }

    if (accessmode == OPEN_ACCESS_WRITEONLY)
    {
#ifdef FS_TRACE
        fs_log("OPEN_ACCESS_WRITEONLY");
#endif
        openmode = OPENMODE_WRITEONLY;
    }

    if (accessmode == OPEN_ACCESS_READWRITE)
    {
#ifdef FS_TRACE
        fs_log("OPEN_ACCESS_READWRITE");
#endif
        openmode = OPENMODE_READWRITE;
    }

#ifdef FS_TRACE
    if (accessmode == OPEN_ACCESS_EXECUTE)
    {
        fs_log("OPEN_ACCESS_EXECUTE");
    }
#endif

    newflag = parms->openflag & OPEN_ACTION_NEW_MASK;

#ifdef FS_TRACE
    if (newflag == OPEN_ACTION_FAIL_IF_NEW)
    {
        fs_log("OPEN_ACTION_FAIL_IF_NEW");
    }
    if (newflag == OPEN_ACTION_CREATE_IF_NEW)
    {
        fs_log("OPEN_ACTION_CREATE_IF_NEW");
    }
#endif

    existflag = parms->openflag & OPEN_ACTION_EXIST_MASK;

#ifdef FS_TRACE
    if (existflag == OPEN_ACTION_OPEN_IF_EXISTS)
    {
        fs_log("OPEN_ACTION_OPEN_IF_EXISTS");
    }
    if (existflag == OPEN_ACTION_FAIL_IF_EXISTS)
    {
        fs_log("OPEN_ACTION_FAIL_IF_EXISTS");
    }
    if (existflag == OPEN_ACTION_REPLACE_IF_EXISTS)
    {
        fs_log("OPEN_ACTION_REPLACE_IF_EXISTS");
    }
#endif

    if ((!Read_Write) &&
        ((accessmode == OPEN_ACCESS_READWRITE) ||
         (accessmode == OPEN_ACCESS_WRITEONLY)))
    {
        fs_log("FS_OPENCREATE() - Write access not enabled");
        return ERROR_WRITE_PROTECT;
    }

    //
    // Direct access open of the whole device
    //
    if (parms->ulOpenMode & OPEN_FLAGS_DASD)
    {
        sb = getvolume(psffsi->sfi_hVPB);
        kernel_printf("OPEN_FLAGS_DASD");
        if ((p_file = _open_by_inode(sb, INODE_DASD, openmode)) == 0)
        {
            kernel_printf("FS_OPENCREATE() - couldn't DASD open %s", pName);
            return ERROR_OPEN_FAILED;
        }
        psffsd->f = p_file;
        psffsi->sfi_tstamp = ST_SCREAT | ST_PCREAT;
        psffsi->sfi_size = p_file->f_inode->i_size;
        psffsi->sfi_position = p_file->f_pos;
        date_unix2dos(p_file->f_inode->i_ctime, &(psffsi->sfi_ctime), &(psffsi->sfi_cdate));
        date_unix2dos(p_file->f_inode->i_atime, &(psffsi->sfi_atime), &(psffsi->sfi_adate));
        date_unix2dos(p_file->f_inode->i_mtime, &(psffsi->sfi_mtime), &(psffsi->sfi_mdate));
        return NO_ERROR;

    }

    //
    // Now that we treated the OPEN_FLAGS_DASD special case, lets treat the general case :
    // Try to open the file readonly
    // Success : the file exists
    //     if !S_ISDIR && !S_ISREG => error
    //     if OPEN_ACTION_FAIL_IF_EXISTS set => error
    //     if OPEN_ACTION_OPEN_IF_EXISTS set
    //         <test file attrs>
    //         change the open mode and return OK
    //     if OPEN_ACTION_REPLACE_IF_EXISTS set
    //         OPEN_ACCESS_READONLY or OPEN_ACCESS_EXECUTE set => error
    //         OPEN_ACCESS_READWRITE or OPEN_ACCESS_WRITEONLY set
    //             truncate
    //             change openmode and return
    // Failure : the file does not exist
    //     OPEN_ACCESS_READONLY or OPEN_ACCESS_EXECUTE set => error
    //     OPEN_ACCESS_READWRITE or OPEN_ACCESS_WRITEONLY set
    //         if OPEN_ACTION_CREATE_IF_NEW set
    //             try to create the file
    //             open the file and return
    //         if OPEN_ACTION_FAIL_IF_NEW   set => error
    rc = ERROR_INVALID_PARAMETER;
    if (parms->iCurDirEnd != CURDIREND_INVALID)
    {
        tmp = pName + parms->iCurDirEnd;
        if ((pcdfsd->u.p_file) && (pcdfsd->u.p_file->f_magic == FILE_MAGIC))
        {
            base = pcdfsd->u.p_file->f_inode;
            if (base)
            {
                sb = base->i_sb;
                rc = NO_ERROR;
            }
        }
    }
    else
    {
        sb = getvolume(psffsi->sfi_hVPB);
        if ((sb) && (sb->s_magic_internal == SUPER_MAGIC))
        {
            tmp = skip_drive(pName);
            base = sb->s_mounted;
            if (base)
            {
                rc = NO_ERROR;
            }
        }
    }

    if (rc != NO_ERROR)
    {
        return rc;
    }

    p_file = open_by_name(base, tmp, openmode);
    if (p_file)
    {                           // The file exists
        //
        // If it's not a regular file or a directory we cannot open
        //

        if (!S_ISREG(p_file->f_inode->i_mode))
        {
//            kernel_printf("Can't FS_OPENCREATE - %s is not a regular file", pName);
            if ((rc = vfs_close(p_file)) != NO_ERROR)
            {
                fs_err(FUNC_FS_OPENCREATE, FUNC_CLOSE, rc, FILE_TEST_C, __LINE__);
                return rc;
            }
            return ERROR_ACCESS_DENIED;
        }
        //
        // if OPEN_ACTION_FAIL_IF_EXISTS set => error
        //
        if (existflag == OPEN_ACTION_FAIL_IF_EXISTS)
        {
#ifdef FS_TRACE
            fs_log("Can't FS_OPENCREATE() - File exists & OPEN_ACTION_FAIL_IF_EXISTS");
#endif
            if ((rc = vfs_close(p_file)) != NO_ERROR)
            {
                fs_err(FUNC_FS_OPENCREATE, FUNC_CLOSE, rc, FILE_TEST_C, __LINE__);
                return rc;
            }
            return ERROR_FILE_EXISTS;
        }

        //
        // if OPEN_ACTION_OPEN_IF_EXISTS : OK
        //
        if (existflag == OPEN_ACTION_OPEN_IF_EXISTS)
        {
            *pAction = FILE_EXISTED;
        }

        //
        // if OPEN_ACTION_REPLACE_IF_EXISTS : truncate
        //
        if (existflag == OPEN_ACTION_REPLACE_IF_EXISTS)
        {
            p_file->f_inode->i_size = psffsi->sfi_size;
            p_file->f_inode->i_op->truncate(p_file->f_inode);
            p_file->f_inode->i_dirt = 1;
            p_file->f_flags = O_TRUNC;
            *pAction = FILE_TRUNCATED;
#if 0
            psffsi->sfi_tstamp = ST_PWRITE | ST_SWRITE;
#else
            /*
             * Time stamping is done by inode routines - Only propagate value.
             */
            psffsi->sfi_tstamp = ST_PWRITE;
#endif

        }
    }
    else
    {                           // The file doesn't exist

        ExtractPath(pName, __StackToFlat(parent));
        ExtractName(pName, __StackToFlat(component));
        //
        // We try to open the parent dir
        //
        if ((dir = open_by_name(sb->s_mounted, Skip_drive(__StackToFlat(parent)), OPENMODE_READONLY)) == 0)
        {
//            kernel_printf("FS_OPENCREATE() - The parent directory %s doesn't seem to exist", parent);
            return ERROR_PATH_NOT_FOUND;
        }

        //
        // The parent dir exists
        //

        //
        // If the file is open for execution : error (it doesn't even exist)
        //
        if (accessmode == OPEN_ACCESS_EXECUTE)
        {
#ifdef FS_TRACE
            fs_log("Can't FS_OPENCREATE() - File doesn't exist & OPEN_ACCESS_EXECUTE");
#endif
            if ((rc = vfs_close(dir)) != NO_ERROR)
            {
                fs_err(FUNC_FS_OPENCREATE, FUNC_CLOSE, rc, FILE_TEST_C, __LINE__);
                return rc;
            }
            return ERROR_FILE_NOT_FOUND;
        }

        //
        // If the file is open for writing or readwrite ...
        //
        if ((accessmode == OPEN_ACCESS_READONLY) ||
            (accessmode == OPEN_ACCESS_READWRITE) ||
            (accessmode == OPEN_ACCESS_WRITEONLY))
        {
            if (newflag == OPEN_ACTION_FAIL_IF_NEW)
            {
#ifdef FS_TRACE
                fs_log("Can't FS_OPENCREATE() - File doesn't exist &  OPEN_ACTION_FAIL_IF_NEW");
#endif
                if ((rc = vfs_close(dir)) != NO_ERROR)
                {
                    fs_err(FUNC_FS_OPENCREATE, FUNC_CLOSE, rc, FILE_TEST_C, __LINE__);
                    return rc;
                }
                return ERROR_OPEN_FAILED;
            }

            if (newflag == OPEN_ACTION_CREATE_IF_NEW)
            {
//                ino_no = dir->f_inode->i_ino;
                inode_parent = dir->f_inode;
                inode_parent->i_count++;
                if ((rc = vfs_close(dir)) != NO_ERROR)
                {
                    fs_err(FUNC_FS_OPENCREATE, FUNC_CLOSE, rc, THISFILE, __LINE__);
                    return rc;
                }
//                inode_parent = iget(sb, ino_no);
                inode_parent->i_count++;
                down(&inode_parent->i_sem);
                rc = inode_parent->i_op->create(inode_parent, __StackToFlat(component), strlen(component), S_IRWXU | S_IFREG, __StackToFlat(&inode));
                up(&inode_parent->i_sem);
                if (rc)
                {
                    kernel_printf("Couldn't create %s", pName);
                    iput(inode_parent);
                    return rc;
                }
                ino_no = inode->i_ino;
                iput(inode_parent);
                iput(inode);
                if ((p_file = _open_by_inode(sb, ino_no, openmode)) == 0)
                {
                    kernel_printf("open_by_inode(%lu) failed in FS_OPENCREATE", ino_no);
                    return ERROR_OPEN_FAILED;
                }
                p_file->f_inode->i_size = psffsi->sfi_size;
                p_file->f_inode->i_dirt = 1;
                p_file->f_flags = O_CREAT;
                *pAction = FILE_CREATED;
#if 0
                psffsi->sfi_tstamp = ST_SCREAT | ST_PCREAT | ST_PWRITE | ST_SWRITE;
#else
                /*
                 * Time stamping is done by inode routines - Only propagate value.
                 */
                psffsi->sfi_tstamp = ST_PCREAT | ST_PWRITE;
#endif

            }

        }

    }





    psffsd->f = p_file;
    /*
     * Time stamping is done by inode routines - Only propagate value.
     */
#if 0
    psffsi->sfi_tstamp |= ST_PREAD | ST_SREAD;
#else
    /*
     * Time stamping is done by inode routines - Only propagate value.
     */
    psffsi->sfi_tstamp |= ST_PREAD;
#endif
    psffsi->sfi_size = p_file->f_inode->i_size;
    psffsi->sfi_position = p_file->f_pos;

//    kernel_printf("date = %u/%u/%u", (pCommon->dateCreate) & 31, (pCommon->dateCreate >> 5) & 15 , (pCommon->dateCreate) >> 9);

    date_unix2dos(p_file->f_inode->i_ctime, &(psffsi->sfi_ctime), &(psffsi->sfi_cdate));
    date_unix2dos(p_file->f_inode->i_atime, &(psffsi->sfi_atime), &(psffsi->sfi_adate));
    date_unix2dos(p_file->f_inode->i_mtime, &(psffsi->sfi_mtime), &(psffsi->sfi_mdate));

    psffsi->sfi_DOSattr = (unsigned char)Linux_To_DOS_Attrs(p_file->f_inode, __StackToFlat(component));
    if (write_through_support)
    {
        if ((parms->ulOpenMode & OPEN_FLAGS_WRITE_THROUGH) ||
            (parms->ulOpenMode & OPEN_FLAGS_NO_CACHE))
        {
            p_file->f_flags |= O_SYNC;
            p_file->f_inode->i_flags |= MS_SYNCHRONOUS;
        }
    }
    return NO_ERROR;

}
示例#21
0
/* If path looks like: A/B/C/D/whatever, it returns A/B/C/D as a malloced
 * string.
 */
char *SLpath_dirname (SLFUTURE_CONST char *drivefile)
{
   SLCONST char *b;
   const char *file;
   char *dir, *drivedir;
   size_t len;

   if (drivefile == NULL) return NULL;
   file = skip_drive (drivefile);

   b = file + strlen (file);

   while (b != file)
     {
	b--;
	if (0 == IS_PATH_SEP(*b))
	  continue;

#ifdef VMS
	b++;		       /* make sure final ] is included */
#else
	/* collapse multiple slashes */
	while ((b != file) && IS_PATH_SEP(*(b-1)))
	  b--;

	if (b == file) b++;
#endif
	break;
     }

   /* now b should point to the character after the slash:
    *    file="zzz/xxxx"
    *       b------^
    */
   if (b == file)
     {
	/* pathological cases -- what is the parent?  For simplicity
	 * simply return the current directory.
	 */
	len = file - drivefile;
	if (NULL == (dir = SLmalloc (len + 1 + strlen(THIS_DIR_STRING))))
	  return NULL;
	strncpy (dir, drivefile, len);
	strcpy (dir + len, THIS_DIR_STRING);
	return dir;
     }

   if (NULL == (drivedir = SLmake_nstring (drivefile, b - drivefile)))
     return NULL;

   dir = drivedir + (file - drivefile);
   len = b - file;		       /* len is from start of file on drive */

#ifndef VMS
   /* handle special cases
    *    /foo/.   --> /foo
    *    /.       --> /
    *    /foo/..  --> /
    * C:/.
    */
   while ((len > 1) && (dir[len-1] == '.'))
     {
	if (IS_PATH_SEP(dir[len-2]))
	  {
	     len--;		       /* lose "." */
	     while ((len > 1) && IS_PATH_SEP(dir[len-1]))
	       len--;		       /* lose "/" */
	     dir[len] = 0;
	     continue;
	  }
	if ((len > 2) && (dir[len-2] == '.') && IS_PATH_SEP(dir[len-3]))
	  {
	     len -= 2;		       /* lose ".." */
	     if (len > 1)
	       {
		  len--;		       /* lose "/" */
		  dir[len] = 0;
		  b = SLpath_basename (dir);   /* will not fail: zzz/xxx --> zzz/x */
		  len = b - dir;
		  while ((len > 1) && IS_PATH_SEP(dir[len-1]))
		    len--;
	       }
	     dir[len] = 0;
	     continue;
	  }

	break;
     }
#endif				       /* not VMS */
   return drivedir;
}
示例#22
0
void minfo(int argc, char **argv, int type)
{
	struct bootsector boot0;
#define boot (&boot0)
	char name[EXPAND_BUF];
	int media;
	int tot_sectors;
	struct device dev;
	char *drive;
	int verbose=0;
	int c;
	Stream_t *Stream;
	struct label_blk_t *labelBlock;
	
	while ((c = getopt(argc, argv, "v")) != EOF) {
		switch (c) {
			case 'v':
				verbose = 1;
				break;
			default:
				usage();
		}
	}

	if(argc == optind)
		usage();

	for(;optind < argc; optind++) {
		if(skip_drive(argv[optind]) == argv[optind])
			usage();
		drive = get_drive(argv[optind], NULL);

		if(! (Stream = find_device(drive, O_RDONLY, &dev, boot, 
					   name, &media, 0)))
			exit(1);

		tot_sectors = DWORD(bigsect);
		SET_INT(tot_sectors, WORD(psect));
		printf("device information:\n");
		printf("===================\n");
		printf("filename=\"%s\"\n", name);
		printf("sectors per track: %d\n", dev.sectors);
		printf("heads: %d\n", dev.heads);
		printf("cylinders: %d\n\n", dev.tracks);
		printf("mformat command line: mformat -t %d -h %d -s %d ",
		       dev.tracks, dev.heads, dev.sectors);
		if(DWORD(nhs))
			printf("-H %d ", DWORD(nhs));
		printf("%s:\n", drive);
		printf("\n");
		
		printf("bootsector information\n");
		printf("======================\n");
		printf("banner:\"%8s\"\n", boot->banner);
		printf("sector size: %d bytes\n", WORD(secsiz));
		printf("cluster size: %d sectors\n", boot->clsiz);
		printf("reserved (boot) sectors: %d\n", WORD(nrsvsect));
		printf("fats: %d\n", boot->nfat);
		printf("max available root directory slots: %d\n", 
		       WORD(dirents));
		printf("small size: %d sectors\n", WORD(psect));
		printf("media descriptor byte: 0x%x\n", boot->descr);
		printf("sectors per fat: %d\n", WORD(fatlen));
		printf("sectors per track: %d\n", WORD(nsect));
		printf("heads: %d\n", WORD(nheads));
		printf("hidden sectors: %d\n", DWORD(nhs));
		printf("big size: %d sectors\n", DWORD(bigsect));

		if(WORD(fatlen)) {
		    labelBlock = &boot->ext.old.labelBlock;
		} else {
		    labelBlock = &boot->ext.fat32.labelBlock;
		}

		printf("physical drive id: 0x%x\n", 
		       labelBlock->physdrive);
		printf("reserved=0x%x\n", 
		       labelBlock->reserved);
		printf("dos4=0x%x\n", 
		       labelBlock->dos4);
		printf("serial number: %08X\n", 
		       _DWORD(labelBlock->serial));
		printf("disk label=\"%11.11s\"\n", 
		       labelBlock->label);
		printf("disk type=\"%8.8s\"\n", 
		       labelBlock->fat_type);

		if(!WORD(fatlen)){
			printf("Big fatlen=%u\n",
			       DWORD(ext.fat32.bigFat));
			printf("Extended flags=0x%04x\n",
			       WORD(ext.fat32.extFlags));
			printf("FS version=0x%04x\n",
			       WORD(ext.fat32.fsVersion));
			printf("rootCluster=%u\n",
			       DWORD(ext.fat32.rootCluster));
			if(WORD(ext.fat32.infoSector) != MAX32)
				printf("infoSector location=%d\n",
				       WORD(ext.fat32.infoSector));
			if(WORD(ext.fat32.backupBoot) != MAX32)
				printf("backup boot sector=%d\n",
				       WORD(ext.fat32.backupBoot));
			displayInfosector(Stream,boot);
		}

		if(verbose) {
			int size;
			unsigned char *buf;

			printf("\n");
			size = WORD(secsiz);
			
			buf = (unsigned char *) malloc(size);
			if(!buf) {
				fprintf(stderr, "Out of memory error\n");
				exit(1);
			}

			size = READS(Stream, buf, (mt_off_t) 0, size);
			if(size < 0) {
				perror("read boot sector");
				exit(1);
			}

			print_sector("Boot sector hexdump", buf, size);
		}
	}

	exit(0);
}