コード例 #1
0
ファイル: filepath.c プロジェクト: karstenw/frontier
boolean filegetdefaultpath ( ptrfilespec fs ) {

	//
	// 2006-06-25 creedon: for Mac, FSRef-ized
	//
	
	#ifdef MACVERSION
	
		*fs = fsdefault;
		
		return ( true );

	#endif

	#ifdef WIN95VERSION
	
		DWORD sz;

		sz = GetCurrentDirectory (257, stringbaseaddress (fsname (fs)));
		
		if (sz == 0) {
			
			oserror (GetLastError ());
			
			return (false);
			}
		
		strcat (stringbaseaddress (fsname (fs)), "\\");

		setstringlength(fsname (fs), sz + 1);
		
		return (true);
		
	#endif		
	} /*filegetdefaultpath*/
コード例 #2
0
ファイル: filepath.c プロジェクト: karstenw/frontier
boolean filesetdefaultpath ( const ptrfilespec fs ) {

	//
	// 2006-06-18 creedon: for Mac, FSRef-ized
	//
	
	#ifdef MACVERSION

		setfserrorparam ( fs );
		
		fsdefault = *fs;
		
		return (true);
		
	#endif

	#ifdef WIN95VERSION
	
		if (isemptystring (fsname (fs)))
			return (true);
		
		if (!SetCurrentDirectory (stringbaseaddress(fsname (fs)))) {
			
			oserror (GetLastError ());
			
			return (false);
			}

		return (true);
		
	#endif
	
	} // filesetdefaultpath
コード例 #3
0
ファイル: bin_fs.c プロジェクト: AitorATuin/radare2
static RBinInfo* info(RBinFile *arch) {
	RBinInfo *ret = NULL;
	const ut8 *bytes;
	ut64 sz;

	if (!arch) return NULL;
	bytes = r_buf_buffer (arch->buf);
	if (!bytes) return NULL;
	sz = arch->buf ? r_buf_size (arch->buf): 0;

	if (!(ret = R_NEW0 (RBinInfo)))
		return NULL;
	ret->file = arch->file? strdup (arch->file): NULL;
	ret->type = strdup ("fs");
	ret->bclass = strdup ("1.0");
	ret->rclass = strdup ("fs");
	ret->os = strdup ("any");
	ret->subsystem = strdup ("unknown");
	ret->machine = strdup ("any");
	ret->arch = fsname (bytes, sz);
	ret->has_va = 0;
	ret->bits = 32;
	ret->big_endian = 0;
	ret->dbg_info = 0;
	return ret;
}
コード例 #4
0
ファイル: fscmd.c プロジェクト: CoryXie/nix-os
static Path*
walkto(char *a, char **lastp)
{
	char *els[Nels], *path;
	int nels;
	Path *p;

	path = fsname(a);
	nels = gettokens(path, els, Nels, "/");
	if(nels < 1){
		free(path);
		error("invalid path");
	}
	if(catcherror()){
		free(path);
		error("walkpath: %r");
	}
	if(lastp != nil){
		p = walkpath(fs->root, els, nels-1);
		*lastp = a + strlen(a) - strlen(els[nels-1]);
	}else
		p = walkpath(fs->root, els, nels);
	free(path);
	noerror();
	if(verb)
		print("walked to %H\n", p->f[p->nf-1]);
	return p;
}
コード例 #5
0
ファイル: filepath.c プロジェクト: karstenw/frontier
boolean filespectopath (const ptrfilespec fs, bigstring bspath) {
	
	//
	// 2006-09-09 creedon: for Mac, FSRef-ized
	//
	// 2.1a7 dmb: if it's a null filespec, return the empty string
	//
	// 1991-12-17 dmb: don't check for folderness if file doesn't exist-- we dont want to generate any errors here
	//
	// 1991-10-14 dmb: make sure folder paths end in :
	//
	// 1991-06-28 dmb:	when you resolve an alias of a volume, the fsspec has a parent dirid of 1.  we catch this as a
	//				special case here, and return the empty string as the path
	//
	
	#ifdef MACVERSION
	
		boolean flfolder;
		
		setemptystring (bspath);

		if (!directorytopath (fs, bspath))
			return (false);
		
		if (!fs->flags.flvolume) {
			
			bigstring bsfile;
			
			fsnametobigstring (&fs->name, bsfile);
			
			pushstring (bsfile, bspath);
			}
		
		if (fileexists (fs, &flfolder))
			if (flfolder)
				assurelastchariscolon (bspath);
		
		return (true);
		
	#endif

	#ifdef WIN95VERSION
	
		// 5.0d12 dmb: use GetFullPath to clean up 8.3 names
		char * fileptr;
		
		copyptocstring (fsname (fs), bspath);
		
		GetFullPathName (bspath, lenbigstring, bspath, &fileptr);

		convertcstring (bspath);
		
		nullterminate (bspath);

		return (true);
		
	#endif
	
	} // filespectopath
コード例 #6
0
ファイル: bin_fs.c プロジェクト: djpohly/radare2
static int check(RBinFile *arch) {
	char *p;
	int ret;

	p = fsname (arch);
	ret = (p)? R_TRUE: R_FALSE;
	free (p);
	return ret;
}
コード例 #7
0
ファイル: bin_fs.c プロジェクト: AnwarMohamed/radare2
static int check_bytes(const ut8 *buf, ut64 length) {
	char *p;
	int ret;
	if (!buf) return R_FALSE;
	p = fsname (buf, length);
	ret = (p)? R_TRUE: R_FALSE;
	free (p);
	return ret;
}
コード例 #8
0
ファイル: fscmd.c プロジェクト: 99years/plan9
static void
fsget(int, char *argv[])
{
	Memblk *f;
	Mfile *m;
	char buf[4096], *nm;
	uvlong off;
	long nr;
	int fd;
	Path *p;

	fd = create(argv[1], OWRITE, 0664);
	if(fd < 0)
		error("create: %r\n");
	nm = fsname(argv[2]);
	if(catcherror()){
		free(nm);
		close(fd);
		error(nil);
	}
	p = walkto(nm, nil);
	f = p->f[p->nf-1];
	rwlock(f, Rd);
	if(catcherror()){
		rwunlock(f, Rd);
		putpath(p);
		error(nil);
	}
	m = f->mf;
	print("get %-30s\t%M\t%5ulld\t%s %ulld refs\n",
		m->name, (ulong)f->d.mode, f->d.length, m->uid, dbgetref(f->addr));
	if((f->d.mode&DMDIR) == 0){
		off = 0;
		for(;;){
			if(fsmemfree() < Mminfree)
				fslru();
			nr = dfpread(f, buf, sizeof buf, off);
			if(nr <= 0)
				break;
			if(write(fd, buf, nr) != nr){
				fprint(2, "%s: error: %r\n", argv[0]);
				break;
			}
			off += nr;
		}
	}
	close(fd);
	noerror();
	noerror();
	rwunlock(f, Rd);
	putpath(p);
	free(nm);
}
コード例 #9
0
ファイル: filepath.c プロジェクト: karstenw/frontier
boolean setfsfile ( ptrfilespec fs, bigstring bsfile ) {

	//
	// 2006-10-18 creedon: for Mac, FSRef-ized
	//
	// 2004-10-26 aradke: Since the getmacfileinfo/foldertest gymnastics do not seem to fit any particular purpose and since
	//			     none of our callers seem to rely it since they usually pass in a file rather than a directory, I
	//			     commented it out.
	// 
	//			     The only time we get called with a directory is apparently by shellopendefaultfile on startup in the
	//			     Carbon/Mach-O build. getapplicationfilespec returns a directory in that case and the code below
	//			     somehow screwed up when called to set the filename to Frontier.root so that it wouldn't be found.
	//
	
	#ifdef MACVERSION
		
		bigstringtofsname (bsfile, &fs->name);
		
		return ( true );
		
	#endif

	#ifdef WIN95VERSION
	
		bigstring bsfolder;
		
		folderfrompath (fsname (fs), bsfolder);
		
		pushstring (bsfile, bsfolder);

		copystring (bsfolder, fsname (fs));

		nullterminate (fsname (fs));

		return (true);
		
	#endif
	
	} // setfsfile
コード例 #10
0
ファイル: ds_lib.cpp プロジェクト: 610152753/tfs-1.4
    int DsLib::check_file_info(DsTask& ds_task)
    {
      GetServerStatusMessage req_gss_msg;
      req_gss_msg.set_status_type(GSS_BLOCK_FILE_INFO);
      req_gss_msg.set_return_row(ds_task.block_id_);

      tbnet::Packet* rsp = NULL;
      NewClient* client = NewClientManager::get_instance().create_client();
      int ret = send_msg_to_server(ds_task.server_id_, client, &req_gss_msg, rsp);

      if (rsp != NULL)
      {
        if (rsp->getPCode() == BLOCK_FILE_INFO_MESSAGE)
        {
          BlockFileInfoMessage* req_bfi_msg = reinterpret_cast<BlockFileInfoMessage*>(rsp);
          FILE_INFO_LIST* file_list = req_bfi_msg->get_fileinfo_list();
          bool found = false;
          for (int32_t i = 0; i < static_cast<int32_t> (file_list->size()); ++i)
          {
            if (file_list->at(i).id_ == ds_task.new_file_id_)
            {
              printf("file found in server: %s\n", tbsys::CNetUtil::addrToString(ds_task.server_id_).c_str());
              tfs::client::FSName fsname(ds_task.block_id_, ds_task.new_file_id_, ds_task.cluster_id_);
              print_file_info(fsname.get_name(), file_list->at(i));
              found = true;
              break;
            }
          }
          if (!found)
          {
            printf("file not found in server: %s\n", tbsys::CNetUtil::addrToString(ds_task.server_id_).c_str());
          }
        }
        else if (rsp->getPCode() == STATUS_MESSAGE)
        {
          printf("get file info fail, error: %s\n", dynamic_cast<StatusMessage*>(rsp)->get_error());
        }
      }
      else
      {
        printf("get NULL respose message, ret: %d\n", ret);
      }

      NewClientManager::get_instance().destroy_client(client);
      return ret;
    }
コード例 #11
0
ファイル: fscmd.c プロジェクト: 99years/plan9
static void
fscat(int, char *argv[])
{
	Memblk *f;
	Mfile *m;
	char buf[4096], *nm;
	uvlong off;
	long nr;
	Path *p;

	nm = fsname(argv[2]);
	if(catcherror()){
		free(nm);
		error(nil);
	}
	p = walkto(nm, nil);
	f = p->f[p->nf-1];
	rwlock(f, Rd);
	if(catcherror()){
		rwunlock(f, Rd);
		putpath(p);
		error(nil);
	}
	m = f->mf;
	print("cat %-30s\t%M\t%5ulld\t%s %ulld refs\n",
		m->name, (ulong)f->d.mode, f->d.length, m->uid, dbgetref(f->addr));
	if((f->d.mode&DMDIR) == 0){
		off = 0;
		for(;;){
			if(fsmemfree() < Mminfree)
				fslru();
			nr = dfpread(f, buf, sizeof buf, off);
			if(nr <= 0)
				break;
			write(1, buf, nr);
			off += nr;
		}
	}
	noerror();
	noerror();
	rwunlock(f, Rd);
	putpath(p);
	free(nm);
}
コード例 #12
0
ファイル: fscmd.c プロジェクト: 99years/plan9
static void
fsrm(int, char *argv[])
{
	Memblk *f, *pf;
	Path *p;
	char *nm;

	nm = fsname(argv[1]);
	if(catcherror()){
		free(nm);
		error(nil);
	}
	p = walkto(nm, nil);	
	if(catcherror()){
		putpath(p);
		error(nil);
	}
	if(p->nf < 2)
		error("short path for rm");
	meltedpath(&p, p->nf-1, 1);
	f = p->f[p->nf-1];
	pf = p->f[p->nf-2];
	rwlock(f, Wr);
	if(catcherror()){
		rwunlock(f, Wr);
		rwunlock(pf, Wr);
		error(nil);
	}
	dfremove(pf, f);
	p->f[p->nf-1] = nil;
	noerror();
	noerror();
	noerror();
	rwunlock(pf, Wr);
	putpath(p);
	free(nm);
}
コード例 #13
0
ファイル: bin_fs.c プロジェクト: djpohly/radare2
static RBinInfo* info(RBinFile *arch) {
	char *p;
	RBinInfo *ret = NULL;
	if (!(ret = R_NEW (RBinInfo)))
		return NULL;
	memset (ret, '\0', sizeof (RBinInfo));
	ret->lang = NULL;
	strncpy (ret->file, arch->file, R_BIN_SIZEOF_STRINGS-1);
	strncpy (ret->rpath, "NONE", R_BIN_SIZEOF_STRINGS-1);
	strncpy (ret->type, "fs", sizeof (ret->type)-1); // asm.arch
	strncpy (ret->bclass, "1.0", sizeof (ret->bclass)-1);
	strncpy (ret->rclass, "fs", sizeof (ret->rclass)-1); // file.type
	strncpy (ret->os, "any", sizeof (ret->os)-1);
	strncpy (ret->subsystem, "unknown", sizeof (ret->subsystem)-1);
	strncpy (ret->machine, "any", sizeof (ret->machine)-1);
	p = fsname (arch);
	strncpy (ret->arch, p, sizeof (ret->arch)-1);
	free (p);
	ret->has_va = 0;
	ret->bits = 32;
	ret->big_endian = 0;
	ret->dbg_info = 0;
	return ret;
}
コード例 #14
0
ファイル: ds_lib.cpp プロジェクト: 610152753/tfs-1.4
    int DsLib::read_file_info(DsTask& ds_task)
    {
      uint64_t server_id = ds_task.server_id_;
      int32_t cluster_id = ds_task.cluster_id_;
      uint32_t block_id = ds_task.block_id_;
      uint64_t file_id = ds_task.new_file_id_;
      int32_t mode = ds_task.mode_;

      FileInfoMessage req_fi_msg;
      req_fi_msg.set_block_id(block_id);
      req_fi_msg.set_file_id(file_id);
      req_fi_msg.set_mode(mode);

      int ret_status = TFS_ERROR;
      NewClient* client = NewClientManager::get_instance().create_client();
      tbnet::Packet* ret_msg = NULL;
      ret_status = send_msg_to_server(server_id, client, &req_fi_msg, ret_msg);
      if ((ret_status == TFS_SUCCESS))
      {
        if (RESP_FILE_INFO_MESSAGE == ret_msg->getPCode())
        {
          RespFileInfoMessage* resp_fi_msg = dynamic_cast<RespFileInfoMessage*> (ret_msg);
          if (resp_fi_msg->get_file_info() != NULL)
          {
            FileInfo file_info;
            memcpy(&file_info, resp_fi_msg->get_file_info(), FILEINFO_SIZE);
            if (file_info.id_ == file_id)
            {
              ret_status = TFS_SUCCESS;
              tfs::client::FSName fsname(block_id, file_id, cluster_id);
              printf("  FILE_NAME:     %s\n", fsname.get_name());
              printf("  BLOCK_ID:      %u\n", fsname.get_block_id());
              printf("  FILE_ID:       %" PRI64_PREFIX "u\n", file_info.id_);
              printf("  OFFSET:        %d\n", file_info.offset_);
              printf("  SIZE:          %d\n", file_info.size_);
              printf("  MODIFIED_TIME: %s\n", Func::time_to_str(file_info.modify_time_).c_str());
              printf("  CREATE_TIME:   %s\n", Func::time_to_str(file_info.create_time_).c_str());
              printf("  STATUS:        %d\n", file_info.flag_);
              printf("  CRC:           %u\n", file_info.crc_);
            }
          }
        }
        else if (STATUS_MESSAGE == ret_msg->getPCode())
        {
          printf("Read file info error:%s", (dynamic_cast<StatusMessage*> (ret_msg))->get_error());
          ret_status = TFS_ERROR;
        }
        else
        {
          printf("message type is error.");
          ret_status = TFS_ERROR;
        }
      }
      else
      {
        fprintf(stderr, "Read file info fail\n");
        ret_status = TFS_ERROR;
      }

      NewClientManager::get_instance().destroy_client(client);
      return ret_status;

    }
コード例 #15
0
ファイル: fscmd.c プロジェクト: 99years/plan9
/*
 * This is unrealistic in that it keeps the file locked
 * during the entire put. This means that we can only give
 * fslru() a chance before each put, and not before each
 * write, because everything is going to be in use and dirty if
 * we run out of memory.
 */
static void
fsput(int, char *argv[])
{
	int fd;
	char *fn;
	Memblk *m, *f;
	Dir *d;
	char buf[4096];
	uvlong off;
	long nw, nr;
	Path *p;
	char *nm;

	fd = open(argv[1], OREAD);
	if(fd < 0)
		error("open: %r\n");
	d = dirfstat(fd);
	if(d == nil){
		error("dirfstat: %r\n");
	}
	nm = fsname(argv[2]);
	if(catcherror()){
		free(nm);
		close(fd);
		free(d);
		error(nil);
	}
	p = walkto(nm, &fn);
	if(catcherror()){
		putpath(p);
		error(nil);
	}
	meltedpath(&p, p->nf, 1);
	m = p->f[p->nf-1];
	if(catcherror()){
		rwunlock(m, Wr);
		error(nil);
	}
	f = dfcreate(m, fn, usrid(d->uid), d->mode&(DMDIR|0777));
	noerror();
	addelem(&p, f);
	decref(f);	/* kept now in p */
	rwlock(f, Wr);
	rwunlock(m, Wr);
	if(catcherror()){
		rwunlock(f, Wr);
		error(nil);
	}
	if((d->mode&DMDIR) == 0){
		off = 0;
		for(;;){
			if(fsmemfree() < Mminfree)
				fslru();
			nr = read(fd, buf, sizeof buf);
			if(nr <= 0)
				break;
			nw = dfpwrite(f, buf, nr, &off);
			dprint("wrote %ld of %ld bytes\n", nw, nr);
			off += nr;
		}
	}
	noerror();
	noerror();
	noerror();
	if(verb)
		print("created %H\nat %H\n", f, m);
	rwunlock(f, Wr);
	free(nm);
	putpath(p);
	close(fd);
	free(d);
}
コード例 #16
0
ファイル: assert.c プロジェクト: dvincent/frontier
	short __assert (char *expr, char *file, short line) {
	
		/*
		On OS X, DebugStr output gets automatically rerouted to stderr
		which in turn gets logged to console.log, viewable via Console.app.
		
		2003-05-26 AR: Include date/time, app name, and app version.
		*/
		
		static boolean flnorentry = false;
		short day, month, year, hour, minute, second;
		tyfilespec myfspec;
		bigstring bs, bslogstamp, bsline, bsfile, bsmessage;
		
		if (flnorentry)
			return (0);
		
		flnorentry = true;
		
		/*get timestamp*/
		
		secondstodatetime (timenow (), &day, &month, &year, &hour, &minute, &second);
		
		numbertostring ((long) year, bs);
		
		pushstring (bs, bslogstamp);
		
		pushchar ('-', bslogstamp);
		
		numbertostring ((long) month, bs);
		
		padwithzeros (bs, 2);
		
		pushstring (bs, bslogstamp);
		
		pushchar ('-', bslogstamp);
		
		numbertostring ((long) day, bs);
		
		padwithzeros (bs, 2);
		
		pushstring (bs, bslogstamp);
		
		pushchar (' ', bslogstamp);
		
		numbertostring ((long) hour, bs);
		
		padwithzeros (bs, 2);
		
		pushstring (bs, bslogstamp);
		
		pushchar (':', bslogstamp);
		
		numbertostring ((long) minute, bs);
		
		padwithzeros (bs, 2);
		
		pushstring (bs, bslogstamp);
		
		pushchar (':', bslogstamp);
		
		numbertostring ((long) second, bs);
		
		padwithzeros (bs, 2);
		
		pushstring (bs, bslogstamp);
		
		pushchar (' ', bslogstamp);

 		/*get filespec for app*/
 
		getapplicationfilespec (nil, &myfspec);
		
		pushstring (fsname (&myfspec), bslogstamp);
		
		pushchar (' ', bslogstamp);
		
		/*get version of app*/
		
		filegetprogramversion (bs);
		
		pushchar ('(', bslogstamp);
		
		pushstring (bs, bslogstamp);
		
		pushchar (')', bslogstamp);
		
		/*get file name*/
		
		moveleft (file, bsfile, (long) lenbigstring);
		
		convertcstring (bsfile);
		
		/*get line number*/
		
		numbertostring ((long) line, bsline);
		
		/*ouput message*/
		
		parsedialogstring (
				"\p\r^0: Assertion failed in file ^1, at line ^2.\r",
				bslogstamp, bsfile, bsline, nil,
				bsmessage);
				
		DebugStr (bsmessage);
		
		/*send message to stderr*/
		
		flnorentry = false;

		return (0);
	} /*__assert*/
コード例 #17
0
ファイル: ds_lib.cpp プロジェクト: 610152753/tfs-1.4
    int DsLib::list_file(DsTask& ds_task)
    {
      uint64_t server_id = ds_task.server_id_;
      int32_t cluster_id = ds_task.cluster_id_;
      uint32_t block_id = ds_task.block_id_;
      int32_t mode = ds_task.mode_;

      GetServerStatusMessage req_gss_msg;
      req_gss_msg.set_status_type(GSS_BLOCK_FILE_INFO);
      req_gss_msg.set_return_row(block_id);

      int ret_status = TFS_ERROR;
      NewClient* client = NewClientManager::get_instance().create_client();
      tbnet::Packet* ret_msg = NULL;
      ret_status = send_msg_to_server(server_id, client, &req_gss_msg, ret_msg);

      //if the information of file can be accessed.
      if ((ret_status == TFS_SUCCESS))
      {
        if (BLOCK_FILE_INFO_MESSAGE == ret_msg->getPCode())
        {
          FILE_INFO_LIST* file_info_list = (dynamic_cast<BlockFileInfoMessage*> (ret_msg))->get_fileinfo_list();
          int32_t i = 0;
          int32_t list_size = file_info_list->size();

          //output file information
          printf("FileList Size = %d\n", list_size);
          if (mode != 0)
          {
            printf(
              "FILE_NAME          FILE_ID             OFFSET        SIZE        USIZE       M_TIME               C_TIME              FLAG CRC\n");
            printf(
              "---------- ---------- ---------- ---------- ----------  ---------- ---------- ---------- ---------- ---------- ---------- ----------\n");

            for (i = 0; i < list_size; i++)
            {
              FileInfo& file_info = file_info_list->at(i);
              tfs::client::FSName fsname(block_id, file_info.id_, cluster_id);
              print_file_info(fsname.get_name(), file_info);
            }
            printf(
              "---------- ---------- ---------- ---------- ----------  ---------- ---------- ---------- ---------- ---------- ---------- ----------\n");
            printf(
              "FILE_NAME          FILE_ID             OFFSET        SIZE        USIZE       M_TIME               C_TIME              FLAG CRC\n");

          }
          else
          {
            // just print file
            for (i = 0; i < list_size; i++)
            {
              FileInfo& file_info = file_info_list->at(i);
              tfs::client::FSName fsname(block_id, file_info.id_, cluster_id);
              fprintf(stdout, "\n%s", fsname.get_name());
            }
            fprintf(stdout, "\n");
          }
          printf("Total : %d files\n", list_size);
        }
        else if (STATUS_MESSAGE == ret_msg->getPCode())
        {
          printf("%s", (dynamic_cast<StatusMessage*> (ret_msg))->get_error());
        }
      }
      else
      {
        fprintf(stderr, "Get File list in Block failure\n");
      }

      NewClientManager::get_instance().destroy_client(client);
      return ret_status;

    }
コード例 #18
0
ファイル: bin_fs.c プロジェクト: AitorATuin/radare2
static int check_bytes(const ut8 *buf, ut64 length) {
	if (!buf || (st64)length <1) return false;
	char *p = fsname (buf, length);
	free (p);
	return p != NULL;
}
コード例 #19
0
ファイル: filepath.c プロジェクト: karstenw/frontier
boolean pathtofilespec ( bigstring bspath, ptrfilespec fs ) {

    //
    // 2010-01-24 creedon: fix for relative paths not working on mac,
    //                     bsfullpath was ending up with :: in it as well as
    //                     the full path to the application, see initfsdefault
    //                     function
    //
	// 2009-08-30 aradke: refactored mac version to make it easier to understand.
	//			fixed bug where a bspath containing a non-existing volume name was accepted as valid,
	//			e.g. filespec("foobar:"), thus deviating from previous behaviour.
	//
	// 2006-10-16 creedon: for Mac, FSRef-ized
	//
	// 5.0d8 dmb: clear fs first thing
	//
	// 2.1b2 dmb: use new fsdefault for building filespec. note that if bspath
    //            isn't a partial path, the vref and dirid will be ignored.
	//
	// 2.1b2 dmb: added special case for empty string.  also, added drive
    //            number interpretation here.
	//
	// 1993-06-11 dmb: if FSMakeFSSpec returns fnfErr, the spec is cool (but
    //                 file doesn't exist)
	//
	// 1991-012-17 dmb: dont append path to default directory if it's a full
    //                  path
	//
	// 1991-07-05 dmb: use FSMakeFSSpec if it's available.  since it only
    //                 returns noErr if the file exists, and we want to handle
	//                 non-existant files, we don't give up right away.
	//
	
	#ifdef MACVERSION
		FSRef fsr;
		bigstring bspathtmp, bsfullpath, bsfile, bsfolder;
		short ix = 1;
		boolean flvolume = false;
	#endif

	#ifdef WIN95VERSION
		bigstring bsfolder;
	#endif

	clearbytes ( fs, sizeof ( *fs ) );

	if ( isemptystring ( bspath ) )
		return ( true );
		
	#ifdef MACVERSION

		// create cleaned-up full path representation of our input suitable for pathtosref
	
		copystring ( bspath, bspathtmp );

		cleanendoffilename ( bspathtmp );
		
		if ( scanstring ( ':', bspath, &ix ) && ( ix > 1 ) ) {
		
			// contains a colon but doesn't start with one, so it must be a full path
			
			if ( ix == stringlength ( bspath ) )	// the colon we found is the last char, so bspath is a volume name
				flvolume = true;
                
			copystring ( bspathtmp, bsfullpath );
			}
            
		else {
		
			// it's a partial path, prefix with default directory (see initfsdefault)
		
			if ( ! filespectopath ( &fsdefault, bsfullpath ) )	// get path of default directory
				return ( false );
                
           // delete first path separator if partial path begins with one because bsfullpath always ends with one
           
			if ( bspathtmp [ 1 ] == chpathseparator )
				deletefirstchar ( bspathtmp );
                
			pushstring ( bspathtmp, bsfullpath );	// append partial path
			}
            
		// now see if the full path resolves 
			
		if ( pathtofsref ( bsfullpath, &fsr ) == noErr ) {

			return ( macmakefilespec ( &fsr, fs ) == noErr );
			}
			
		// full path did not resolve but we actually only require the parent folder to exist
		
		if ( ! flvolume ) {		// volumes don't have a parent folder
		
			filefrompath ( bsfullpath, bsfile );
			
			folderfrompath ( bsfullpath, bsfolder );

			if ( pathtofsref ( bsfolder, &fsr ) == noErr ) {
				
				clearfilespec ( fs );
				
				fs->ref = fsr;
				
				bigstringtofsname ( bsfile, &fs->name );
			
				return ( true );
				}
			}
		
		return ( false );
		
	#endif

	#ifdef WIN95VERSION
	
		copystring (bspath, fsname (fs));

		folderfrompath (bspath, bsfolder);

		if ((isemptystring (bsfolder)) && (! fileisvolume(fs))) {

			filegetdefaultpath (fs);

			pushstring (bspath, fsname (fs));
			}
		
		nullterminate (fsname (fs));
		
		return (true);

	#endif

	} // pathtofilespec