Beispiel #1
0
bool IsFullDirectory(const String& d) {
	if(IsFullPath(d)) {
		FindFile ff(d);
		if(ff) return ff.IsDirectory();
	}
	return false;
}
Beispiel #2
0
String GetExeFilePath()
{
	static String exepath;
	ONCELOCK {
		const char *exe = procexepath_();
		if(*exe)
			exepath = exe;
		else {
			String x = Argv0__;
			if(IsFullPath(x) && FileExists(x))
				exepath = x;
			else {
				exepath = GetHomeDirFile("upp");
				Vector<String> p = Split(FromSystemCharset(Environment().Get("PATH")), ':');
				if(x.Find('/') >= 0)
					p.Add(GetCurrentDirectory());
				for(int i = 0; i < p.GetCount(); i++) {
					String ep = NormalizePath(AppendFileName(p[i], x));
					if(FileExists(ep))
						exepath = ep;
				}
			}
		}
	}
	return exepath;
}
Beispiel #3
0
// We should return 'true' even if resulting path is shorter than MAX_PATH,
// because we can also use this function to open files with non-standard
// characters, even if their path length is normal.
bool GetWinLongPath(const wchar *Src,wchar *Dest,size_t MaxSize)
{
  const wchar *Prefix=L"\\\\?\\";
  const size_t PrefixLength=4;
  bool FullPath=IsDiskLetter(Src) && IsPathDiv(Src[2]);
  size_t SrcLength=wcslen(Src);
  if (IsFullPath(Src)) // Paths in d:\path\name format.
  {
    if (IsDiskLetter(Src))
    {
      if (MaxSize<=PrefixLength+SrcLength)
        return false;
      wcsncpy(Dest,Prefix,PrefixLength);
      wcscpy(Dest+PrefixLength,Src);
      return true;
    }
    else
      if (Src[0]=='\\' && Src[1]=='\\')
      {
        if (MaxSize<=PrefixLength+SrcLength+2)
          return false;
        wcsncpy(Dest,Prefix,PrefixLength);
        wcscpy(Dest+PrefixLength,L"UNC");
        wcscpy(Dest+PrefixLength+3,Src+1);
        return true;
      }
    // We may be here only if we modify IsFullPath in the future.
    return false;
  }
  else
  {
    wchar CurDir[NM];
    DWORD DirCode=GetCurrentDirectory(ASIZE(CurDir)-1,CurDir);
    if (DirCode==0 || DirCode>ASIZE(CurDir)-1)
      return false;

    if (IsPathDiv(Src[0])) // Paths in \path\name format.
    {
      if (MaxSize<=PrefixLength+SrcLength+2)
        return false;
      wcsncpy(Dest,Prefix,PrefixLength);
      wcsncpy(Dest+PrefixLength,CurDir,2); // Copy drive letter 'd:'.
      wcscpy(Dest+PrefixLength+2,Src);
      return true;
    }
    else  // Paths in path\name format.
    {
      AddEndSlash(CurDir,ASIZE(CurDir));
      if (MaxSize<=PrefixLength+wcslen(CurDir)+SrcLength)
        return false;
      wcsncpy(Dest,Prefix,PrefixLength);
      wcscpy(Dest+PrefixLength,CurDir);
      wcsncatz(Dest,Src,MaxSize);
      return true;
    }
  }
  return false;
}
Beispiel #4
0
bool FileSelector::Execute(bool open, const char *title)
{
	Ctrl::ReleaseCtrlCapture();
	if(!title)
		title = open ? t_("Open") : t_("Save as");
	Ctrl *w = Ctrl::GetActiveWindow();
	GtkWidget *fc = gtk_file_chooser_dialog_new(title, w ? w->gtk() : NULL,
	                                            open ? GTK_FILE_CHOOSER_ACTION_OPEN
	                                                 : GTK_FILE_CHOOSER_ACTION_SAVE,
	                                            GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
	                                            open ? GTK_STOCK_OPEN : GTK_STOCK_SAVE, GTK_RESPONSE_OK,
	                                            NULL);
	gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(fc), confirm);
	gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(fc), true);
	gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(fc), multi);
	gtk_file_chooser_set_show_hidden(GTK_FILE_CHOOSER(fc), hidden);
	
	if(IsFullPath(ipath)) {
		FindFile ff(ipath);
		if(ff)
			if(ff.IsFolder())
				gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(fc), ipath);
			else
				gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(fc), ipath);
		else {
			gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(fc), GetFileFolder(ipath));
			gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(fc), GetFileName(ipath));
		}
	}
	else
		gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(fc), ipath);
	ipath.Clear();
	for(int i = 0; i < type.GetCount(); i++) {
	    GtkFileFilter *filter = gtk_file_filter_new();
	    gtk_file_filter_set_name(filter, type[i].a);
	    gtk_file_filter_add_pattern(filter, type[i].b);
	    gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fc), filter);
	    if(i == activetype)
			gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(fc), filter);
	}
	bool ret = false;
	path.Clear();
	if(gtk_dialog_run(GTK_DIALOG(fc)) == GTK_RESPONSE_OK) {
		GSList *list = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(fc));
		if(list) {
			GSList *l;
			for(l = list; l; l = l->next) {
				path.Add((const char *)l->data);
				g_free(l->data);
			}
			g_slist_free (list);
		}
		ret = true;
	}
	gtk_widget_destroy(fc);
	return ret;
}
Beispiel #5
0
LPSTR
ReadFilePush(LPSTR pszfile)
{
    FILE *pf;

    assert(Frb.fOpen);
    OpenFilePush(IsFullPath(pszfile) ? "" : Frb.pszFile, pszfile,
                 Frb.pszCommentToEOL, &pf);
    return(ReadLine(Frb.pf));
}
Beispiel #6
0
String Nest::PackagePath0(const String& name)
{
	String uppfile = NativePath(name);
	if(IsFullPath(uppfile)) return NormalizePath(uppfile);
	Vector<String> d = GetUppDirs();
	String p;
	for(int i = 0; i < d.GetCount(); i++) {
		p = NormalizePath(AppendFileName(AppendFileName(d[i], uppfile),
		                  GetFileName(uppfile)) + ".upp");
		if(FileExists(p)) return p;
	}
	return d.GetCount() ? NormalizePath(AppendFileName(AppendFileName(d[0], uppfile),
		                                GetFileName(uppfile)) + ".upp") : "";
}
Beispiel #7
0
String NormalizePath(const char *path, const char *currdir)
{
	String join_path;
	if(!IsFullPath(path))
		path = join_path = AppendFileName(currdir, path);
	String out;
	if(*path && path[1] == ':') {
		out << path[0] << ":\\";
		path += 3;
	}
	else
	if(path[0] == '\\' && path[1] == '\\') {
		out = "\\\\";
		path += 2;
	}
	else
	if(sDirSep(*path)) {
		if(*currdir)
			out << *currdir << ':';
		out.Cat(DIR_SEP);
		path++;
	}
	int outstart = out.GetLength();
	while(*path) {
		if(sDirSep(*path)) {
			while(sDirSep(*path))
				path++;
			if(*path == '\0')
				break;
			if(out.IsEmpty() || *out.Last() != DIR_SEP)
				out.Cat(DIR_SEP);
		}
		const char *b = path;
		while(*path && !sDirSep(*path))
			path++;
		if(path - b == 1 && *b == '.')
			; //no-op
		else if(path - b == 2 && *b == '.' && b[1] == '.') {
			const char *ob = ~out + outstart, *oe = out.End();
			if(oe - 1 > ob && oe[-1] == DIR_SEP)
				oe--;
			while(oe > ob && oe[-1] != DIR_SEP)
				oe--;
			out.Trim((int)(oe - out.Begin()));
		}
		else
			out.Cat(b, (int)(path - b));
	}
	return out;
}
Beispiel #8
0
String GetFileOnPath(const char* file, const char* paths, bool current, const char *curdir) {
	String ufn = NativePath(file);
	if(IsFullPath(ufn))
		return ufn;
	String fn;
#ifdef PLATFORM_WINCE
	if(current && curdir && FileExists(fn = NormalizePath(ufn, curdir)))
		;
#else
	String cd = curdir;
	if(!curdir)
		cd = GetCurrentDirectory();
	if(current && FileExists(fn = NormalizePath(ufn, cd)))
		;
#endif
	else if(paths)
	{
		fn = Null;
		while(*paths) {
			const char* start = paths;
#ifdef PLATFORM_WIN32
			while(*paths && *paths != ';')
				paths++;
#else
			while(*paths && *paths != ';' && *paths != ':')
				paths++;
#endif
			String dir(start, (int)(paths - start));
			if(!dir.IsEmpty()) {
#ifdef PLATFORM_WINCE
				dir = NormalizePath(AppendFileName(NativePath(dir), ufn));
#else
				dir = NormalizePath(AppendFileName(NativePath(dir), ufn), cd);
#endif
				if(FileExists(dir)) {
					fn = dir;
					break;
				}
			}
			if(*paths)
				paths++;
		}
	}
	return fn;
}
Beispiel #9
0
bool CommandData::ExclCheckArgs(StringList *Args,char *CheckName,bool CheckFullPath)
{
  char *Name=ConvertPath(CheckName,NULL);
  char FullName[NM],*CurName;
  *FullName=0;
  Args->Rewind();
  while ((CurName=Args->GetString())!=NULL)
#ifndef SFX_MODULE
    if (CheckFullPath && IsFullPath(CurName))
    {
      if (*FullName==0)
        ConvertNameToFull(CheckName,FullName);
      if (CmpName(CurName,FullName,MATCH_WILDSUBPATH))
        return(true);
    }
    else
#endif
      if (CmpName(ConvertPath(CurName,NULL),Name,MATCH_WILDSUBPATH))
        return(true);
  return(false);
}
Beispiel #10
0
// Check the path length and display the error message if it is too long.
void ErrorHandler::CheckLongPathErrMsg(const char *FileName,const wchar *FileNameW)
{
#if defined(_WIN_ALL) && !defined(_WIN_CE) && !defined (SILENT) && defined(MAX_PATH)
  if (GetLastError()==ERROR_PATH_NOT_FOUND)
  {
    wchar WideFileName[NM];
    GetWideName(FileName,FileNameW,WideFileName,ASIZE(WideFileName));
    size_t NameLength=wcslen(WideFileName);
    if (!IsFullPath(WideFileName))
    {
      wchar CurDir[NM];
      GetCurrentDirectoryW(ASIZE(CurDir),CurDir);
      NameLength+=wcslen(CurDir)+1;
    }
    if (NameLength>MAX_PATH)
    {
      Log(NULL,St(MMaxPathLimit),MAX_PATH);
    }
  }
#endif
}
Beispiel #11
0
FILE *
efopen(char *env)
{
	char	*t, *p;
	int	port, sock;
	FILE	*f = 0;

	unless (t = getenv(env)) return (0);
	if (IsFullPath(t)) {
		f = fopen(t, "a");
	} else if ((p = strchr(t, ':')) && ((port = atoi(p+1)) > 0)) {
		*p = 0;
		sock = tcp_connect(t, port);
		*p = ':';
		if (sock >= 0) f = fdopen(sock, "w");
	} else {
		unless (f = fopen(DEV_TTY, "w")) f = fdopen(2, "w");
	}
	if (f) setvbuf(f, 0, _IONBF, 0);
	return (f);
}
Beispiel #12
0
void ConvertNameToFull(const wchar *Src,wchar *Dest,size_t MaxSize)
{
  if (Src==NULL || *Src==0)
  {
    if (MaxSize>0)
      *Dest=0;
    return;
  }
#ifdef _WIN_ALL
  {
    wchar FullName[NM],*NamePtr;
    DWORD Code=GetFullPathName(Src,ASIZE(FullName),FullName,&NamePtr);
    if (Code==0 || Code>ASIZE(FullName))
    {
      wchar LongName[NM];
      if (GetWinLongPath(Src,LongName,ASIZE(LongName)))
        Code=GetFullPathName(LongName,ASIZE(FullName),FullName,&NamePtr);
    }
    if (Code!=0 && Code<ASIZE(FullName))
      wcsncpyz(Dest,FullName,MaxSize);
    else
      if (Src!=Dest)
        wcsncpyz(Dest,Src,MaxSize);
  }
#elif defined(_UNIX)
  if (IsFullPath(Src))
    *Dest=0;
  else
  {
    char CurDirA[NM];
    if (getcwd(CurDirA,ASIZE(CurDirA))==NULL)
      *CurDirA=0;
    CharToWide(CurDirA,Dest,MaxSize);
    AddEndSlash(Dest,MaxSize);
  }
  wcsncatz(Dest,Src,MaxSize);
#else
  wcsncpyz(Dest,Src,MaxSize);
#endif
}
Beispiel #13
0
void ErrorHandler::CreateErrorMsg(const char *ArcName,const char *FileName)
{
#ifndef SILENT
  Log(ArcName && *ArcName ? ArcName:NULL,St(MCannotCreate),FileName);
  Alarm();
#if defined(_WIN_32) && !defined(_WIN_CE) && !defined(SFX_MODULE) && defined(MAX_PATH)
  if (GetLastError()==ERROR_PATH_NOT_FOUND)
  {
    size_t NameLength=strlen(FileName);
    if (!IsFullPath(FileName))
    {
      char CurDir[NM];
      GetCurrentDirectory(sizeof(CurDir),CurDir);
      NameLength+=strlen(CurDir)+1;
    }
    if (NameLength>MAX_PATH)
    {
      Log(ArcName && *ArcName ? ArcName:NULL,St(MMaxPathLimit),MAX_PATH);
    }
  }
#endif
  SysErrMsg();
#endif
}
Beispiel #14
0
bool CommandData::ExclCheckArgs(StringList *Args,bool Dir,char *CheckName,bool CheckFullPath,int MatchMode)
{
  char *Name=ConvertPath(CheckName,NULL);
  char FullName[NM];
  char CurMask[NM+1]; // We reserve the space to append "*" to mask.
  *FullName=0;
  Args->Rewind();
  while (Args->GetString(CurMask,ASIZE(CurMask)-1))
  {
    char *LastMaskChar=PointToLastChar(CurMask);
    bool DirMask=IsPathDiv(*LastMaskChar); // Mask for directories only.

    if (Dir)
    {
      // CheckName is a directory.
      if (DirMask)
      {
        // We process the directory and have the directory exclusion mask.
        // So let's convert "mask\" to "mask" and process it normally.
        
        *LastMaskChar=0;
      }
      else
      {
        // If mask has wildcards in name part and does not have the trailing
        // '\' character, we cannot use it for directories.
      
        if (IsWildcard(PointToName(CurMask)))
          continue;
      }
    }
    else
    {
      // If we process a file inside of directory excluded by "dirmask\".
      // we want to exclude such file too. So we convert "dirmask\" to
      // "dirmask\*". It is important for operations other than archiving.
      // When archiving, directory matched by "dirmask\" is excluded
      // from further scanning.

      if (DirMask)
        strcat(CurMask,"*");
    }

#ifndef SFX_MODULE
    if (CheckFullPath && IsFullPath(CurMask))
    {
      // We do not need to do the special "*\" processing here, because
      // onlike the "else" part of this "if", now we convert names to full
      // format, so they all include the path, which is matched by "*\"
      // correctly. Moreover, removing "*\" from mask would break
      // the comparison, because now all names have the path.

      if (*FullName==0)
        ConvertNameToFull(CheckName,FullName);
      if (CmpName(CurMask,FullName,MatchMode))
        return(true);
    }
    else
#endif
    {
      char NewName[NM+2],*CurName=Name;
      if (CurMask[0]=='*' && IsPathDiv(CurMask[1]))
      {
        // We want "*\name" to match 'name' not only in subdirectories,
        // but also in the current directory. We convert the name
        // from 'name' to '.\name' to be matched by "*\" part even if it is
        // in current directory.
        NewName[0]='.';
        NewName[1]=CPATHDIVIDER;
        strncpyz(NewName+2,Name,ASIZE(NewName)-2);
        CurName=NewName;
      }

      if (CmpName(ConvertPath(CurMask,NULL),CurName,MatchMode))
        return(true);
    }
  }
  return(false);
}
Beispiel #15
0
bool IsTopicGroup(const char *path)
{
	return ToLower(GetFileExt(path)) == ".tpp" && (!IsFullPath(path) || !FileExists(path));
}
Beispiel #16
0
BOOL
SetupReadFile(
    LPSTR pszdir,
    LPSTR pszfile,
    LPSTR pszCommentToEOL,
    FILE **ppf
    )
{
    char path[DB_MAX_PATH_LENGTH];

    assert(!Frb.fOpen);
    assert(Frb.pf == NULL);
    assert(Frb.pszFile == NULL);
    Frb.fMakefile = strcmp(pszCommentToEOL, "#") == 0;
    Frb.DateTime.value = 0;

    strcpy(path, pszdir);
    if (Frb.pfrbNext != NULL) {         // if a nested open
        LPSTR p;

        if (Frb.fMakefile && !IsFullPath(pszfile)) {

            // nmake handles relative includes in makefiles by
            // attempting to locate the file relative to each makefile
            // in the complete include chain.

            FILEREADBUF *pfrb;

            for (pfrb = Frb.pfrbNext; pfrb != NULL; pfrb = pfrb->pfrbNext) {
                assert(pfrb->pszFile != NULL);

                strcpy(path, pfrb->pszFile);
                p = FindLastPathSeparator(path);
                if (p != NULL) {
                    *p = '\0';
                }

                if (ProbeFile(path, pszfile) != -1) {
                    break;
                }
            }

            if (pfrb == NULL) {
                // Unable to find file anywhere along path.
                return FALSE;
            }
        } else {
            p = FindLastPathSeparator(path);
            if (p != NULL) {
                *p = '\0';
            }
        }
    }

    if (!MyOpenFile(path, pszfile, "rb", ppf, TRUE)) {
        *ppf = NULL;
        return(FALSE);
    }
    if (Frb.fMakefile) {
        Frb.DateTime = (*pDateTimeFile)(path, pszfile);
    }
    Frb.cLine = 0;
    Frb.cNull = 0;
    Frb.cbTotal = 0;
    Frb.pf = *ppf;
    Frb.fEof = FALSE;
    Frb.pszCommentToEOL = pszCommentToEOL;
    Frb.cbCommentToEOL = strlen(pszCommentToEOL);

    if (fseek(Frb.pf, 0L, SEEK_END) != -1) {
        Frb.cbFile = ftell(Frb.pf);
        if (fseek(Frb.pf, 0L, SEEK_SET) == -1) {
            Frb.cbFile = 0;
        }
    } else {
        Frb.cbFile = 0;
    }

    Frb.cbBuffer = BigBufSize;
    if (Frb.pfrbNext != NULL) {
        if (Frb.cbBuffer > Frb.cbFile + 1) {
            Frb.cbBuffer = Frb.cbFile + 1;
        }
        AllocMem(Frb.cbBuffer, (VOID **) &Frb.pbBuffer, MT_IOBUFFER);
    } else {
        Frb.pbBuffer = BigBuf;
    }
    if (!ReadBuf(Frb.pf)) {
        fclose(Frb.pf);
        Frb.pf = *ppf = NULL;
        if (Frb.pfrbNext != NULL) {
            FreeMem((VOID **) &Frb.pbBuffer, MT_IOBUFFER);
        }
        return(FALSE);          // zero byte file
    }
    if (path[0] != '\0') {
        strcat(path, PATH_SEPARATOR);
    }
    strcat(path, pszfile);
    MakeString(&Frb.pszFile, path, TRUE, MT_FRBSTRING);
    Frb.fOpen = TRUE;
    if (Frb.fMakefile && DEBUG_4) {
        BuildError(
            "Opening file: cbFile=%lu cbBuf=%lu\n",
            Frb.cbTotal,
            Frb.cbBuffer);
    }
    return(TRUE);
}
Beispiel #17
0
bool IsFullRootPath(const wchar *Path)
{
  return IsFullPath(Path) || IsPathDiv(Path[0]);
}
Beispiel #18
0
String SourcePath(const String& package, const String& file) {
	if(IsFullPath(file)) return NativePath(file);
	return NormalizePath(AppendFileName(GetFileFolder(PackagePath(package)), file));
}
Beispiel #19
0
bool MakeBuild::BuildPackage(const Workspace& wspc, int pkindex, int pknumber, int pkcount,
	String mainparam, String outfile, Vector<String>& linkfile, String& linkopt, bool link)
{
	String package = wspc[pkindex];
	String mainpackage = wspc[0];
	const Package& pkg = wspc.package[pkindex];
	VectorMap<String, String> bm = GetMethodVars(method);
	if(bm.GetCount() == 0) {
		PutConsole("Invalid build method");
		ConsoleShow();
		return false;
	}
	One<Host> host = CreateHost(false);
	if(!IsNull(onefile)) {
		OneFileHost *h = new OneFileHost;
		h->host = host;
		h->onefile = onefile;
		host = h;
	}
	One<Builder> b = CreateBuilder(~host);
	if(!b)
		return false;
	b->config = PackageConfig(wspc, pkindex, bm, mainparam, *host, *b);
	const TargetMode& m = targetmode == 0 ? debug : release;
	b->version = m.version;
	b->method = method;
	b->outdir = OutDir(b->config, package, bm);
	host->RealizeDir(b->outdir);
	String mainfn = Null;
	Index<String> mcfg = PackageConfig(wspc, 0, bm, mainparam, *host, *b, &mainfn);
	HdependClearDependencies();
	for(int i = 0; i < pkg.GetCount(); i++) {
		const Array<OptItem>& f = pkg[i].depends;
		for(int j = 0; j < f.GetCount(); j++)
			if(MatchWhen(f[j].when, mcfg.GetKeys()))
				HdependAddDependency(SourcePath(package, pkg[i]), SourcePath(package, f[j].text));
	}
	String tout = OutDir(mcfg, mainpackage, bm, use_target);
	host->RealizeDir(tout);
	if(IsNull(mainfn))
		mainfn = GetFileTitle(mainpackage) + b->GetTargetExt();
	if(!IsNull(outfile))
		target = NormalizePath(outfile, tout);
	else {
		if(m.target_override && !IsNull(m.target) && IsFolder(m.target))
			target = host->NormalizePath(AppendFileName(m.target, mainfn));
		else
		if(m.target_override && (IsFullPath(m.target) || *m.target == '/' || *m.target == '\\'))
			target = m.target;
		else
		if(m.target_override && !IsNull(m.target))
			target = host->NormalizePath(AppendFileName(tout, m.target));
		else
		if(IsFullPath(mainfn))
			target = mainfn;
		else
			target = host->NormalizePath(AppendFileName(tout, mainfn));
	}
	b->target = target;
	b->mainpackage = mainpackage;
	if(IsNull(onefile)) {
		String out;
		out << "----- " << package << " ( " << Join(b->config.GetKeys(), " ") << " )";
		if(pkcount > 1)
			out << " (" << (pknumber + 1) << " / " << pkcount << ')';
		PutConsole(out);
	}
	else
		b->config.FindAdd("NOLIB");
	bool ok = b->BuildPackage(package, linkfile, linkopt,
		                      GetAllUses(wspc, pkindex),
		                      GetAllLibraries(wspc, pkindex, bm, mainparam, *host, *b),
		                      targetmode - 1);
	Vector<String> errors = PickErrors();
	host->DeleteFile(errors);
	if(!ok || !errors.IsEmpty())
		return false;
	if(link) {
		ok = b->Link(linkfile, linkopt, GetTargetMode().createmap);
		errors = PickErrors();
		host->DeleteFile(errors);
		if(!ok || !errors.IsEmpty())
			return false;
	}
	return true;
}
Beispiel #20
0
static void LoadIniStream(Stream& in, VectorMap<String, String>& key, const char *sfile)
{
	bool env = false;
	while(!in.IsEof()) {
		String line = in.GetLine();
		CParser p(line);
		if(p.IsId()) {
			String k = p.ReadId();
			if(p.Char('=')) {
				String h = TrimBoth((String)p.GetSpacePtr());
				if(env) {
					String hh;
					const char *s = ~h;
					while(*s) {
						if(*s == '$') {
							s++;
							if(*s == '$') {
								hh.Cat('$');
								s++;
							}
							else {
								String id;
								if (*s == '{') {
									while(*++s != '}')
										id.Cat(*s);
									s++;
								} else {
									while(iscid(*s))
										id.Cat(*s++);
								}
								hh.Cat(GetEnv(id));
							}
						}
						else
							hh.Cat(*s++);
					}
					key.Add(k, hh);
				}
				else
					key.Add(k, h);
			}
		}
		else
		if(p.Char('@')) {
			if(p.Id("include")) {
				String fn = p.GetPtr();
				if(!IsFullPath(fn) && sfile)
					fn = AppendFileName(GetFileFolder(GetFullPath(sfile)), fn);
				LoadIniFile(fn, key);
			}
			else
			if(p.Id("end"))
				return;
			else
			if(p.Id("replace-env"))
				env = true;
			else
			if(p.Id("ignore-env"))
				env = false;
		}
	}
}
Beispiel #21
0
bool CreateReparsePoint(CommandData *Cmd,const wchar *Name,FileHeader *hd)
{
  static bool PrivSet=false;
  if (!PrivSet)
  {
    SetPrivilege(SE_RESTORE_NAME);
    // Not sure if we really need it, but let's request anyway.
    SetPrivilege(SE_CREATE_SYMBOLIC_LINK_NAME);
    PrivSet=true;
  }

  const DWORD BufSize=sizeof(REPARSE_DATA_BUFFER)+2*NM+1024;
  Array<byte> Buf(BufSize);
  REPARSE_DATA_BUFFER *rdb=(REPARSE_DATA_BUFFER *)&Buf[0];

  wchar SubstName[NM];
  wcsncpyz(SubstName,hd->RedirName,ASIZE(SubstName));
  size_t SubstLength=unrar_wcslen(SubstName);

  wchar PrintName[NM],*PrintNameSrc=SubstName,*PrintNameDst=PrintName;
  bool WinPrefix=unrar_wcsncmp(PrintNameSrc,L"\\??\\",4)==0;
  if (WinPrefix)
    PrintNameSrc+=4;
  if (WinPrefix && unrar_wcsncmp(PrintNameSrc,L"UNC\\",4)==0)
  {
    *(PrintNameDst++)='\\'; // Insert second \ in beginning of share name.
    PrintNameSrc+=3;
  }
  unrar_wcscpy(PrintNameDst,PrintNameSrc);

  size_t PrintLength=unrar_wcslen(PrintName);

  bool AbsPath=WinPrefix;
  // IsFullPath is not really needed here, AbsPath check is enough.
  // We added it just for extra safety, in case some Windows version would
  // allow to create absolute targets with SYMLINK_FLAG_RELATIVE.
  if (!Cmd->AbsoluteLinks && (AbsPath || IsFullPath(hd->RedirName) ||
      !IsRelativeSymlinkSafe(hd->FileName,hd->RedirName)))
    return false;

#ifndef NOFILECREATE
  CreatePath(Name,true);

  // 'DirTarget' check is important for Unix symlinks to directories.
  // Unix symlinks do not have their own 'directory' attribute.
  if (hd->Dir || hd->DirTarget)
  {
    if (!CreateDirectory(Name,NULL))
      return false;
  }
  else
  {
    HANDLE hFile=CreateFile(Name,GENERIC_WRITE,0,NULL,CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
    if (hFile == INVALID_HANDLE_VALUE)
      return false;
    CloseHandle(hFile);
  }
#endif

  if (hd->RedirType==FSREDIR_JUNCTION)
  {
    rdb->ReparseTag=IO_REPARSE_TAG_MOUNT_POINT;
    rdb->ReparseDataLength=USHORT(
      sizeof(rdb->MountPointReparseBuffer.SubstituteNameOffset)+
      sizeof(rdb->MountPointReparseBuffer.SubstituteNameLength)+
      sizeof(rdb->MountPointReparseBuffer.PrintNameOffset)+
      sizeof(rdb->MountPointReparseBuffer.PrintNameLength)+
      (SubstLength+1)*sizeof(WCHAR)+(PrintLength+1)*sizeof(WCHAR));
    rdb->Reserved=0;

    rdb->MountPointReparseBuffer.SubstituteNameOffset=0;
    rdb->MountPointReparseBuffer.SubstituteNameLength=USHORT(SubstLength*sizeof(WCHAR));
    unrar_wcscpy(rdb->MountPointReparseBuffer.PathBuffer,SubstName);

    rdb->MountPointReparseBuffer.PrintNameOffset=USHORT((SubstLength+1)*sizeof(WCHAR));
    rdb->MountPointReparseBuffer.PrintNameLength=USHORT(PrintLength*sizeof(WCHAR));
    unrar_wcscpy(rdb->MountPointReparseBuffer.PathBuffer+SubstLength+1,PrintName);
  }
  else
    if (hd->RedirType==FSREDIR_WINSYMLINK || hd->RedirType==FSREDIR_UNIXSYMLINK)
    {
      rdb->ReparseTag=IO_REPARSE_TAG_SYMLINK;
      rdb->ReparseDataLength=USHORT(
        sizeof(rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset)+
        sizeof(rdb->SymbolicLinkReparseBuffer.SubstituteNameLength)+
        sizeof(rdb->SymbolicLinkReparseBuffer.PrintNameOffset)+
        sizeof(rdb->SymbolicLinkReparseBuffer.PrintNameLength)+
        sizeof(rdb->SymbolicLinkReparseBuffer.Flags)+
        (SubstLength+1)*sizeof(WCHAR)+(PrintLength+1)*sizeof(WCHAR));
      rdb->Reserved=0;

      rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset=0;
      rdb->SymbolicLinkReparseBuffer.SubstituteNameLength=USHORT(SubstLength*sizeof(WCHAR));
      unrar_wcscpy(rdb->SymbolicLinkReparseBuffer.PathBuffer,SubstName);

      rdb->SymbolicLinkReparseBuffer.PrintNameOffset=USHORT((SubstLength+1)*sizeof(WCHAR));
      rdb->SymbolicLinkReparseBuffer.PrintNameLength=USHORT(PrintLength*sizeof(WCHAR));
      unrar_wcscpy(rdb->SymbolicLinkReparseBuffer.PathBuffer+SubstLength+1,PrintName);

      rdb->SymbolicLinkReparseBuffer.Flags=AbsPath ? 0:SYMLINK_FLAG_RELATIVE;
    }
    else
      return false;

  HANDLE hFile=CreateFile(Name,GENERIC_READ|GENERIC_WRITE,0,NULL,
               OPEN_EXISTING,FILE_FLAG_OPEN_REPARSE_POINT| 
               FILE_FLAG_BACKUP_SEMANTICS,NULL);
  if (hFile==INVALID_HANDLE_VALUE)
    return false;

  DWORD Returned;
  if (!DeviceIoControl(hFile,FSCTL_SET_REPARSE_POINT,rdb, 
      FIELD_OFFSET(REPARSE_DATA_BUFFER,GenericReparseBuffer)+
      rdb->ReparseDataLength,NULL,0,&Returned,NULL))
  { 
    CloseHandle(hFile);
    uiMsg(UIERROR_SLINKCREATE,UINULL,Name);
    if (GetLastError()==ERROR_PRIVILEGE_NOT_HELD)
      uiMsg(UIERROR_NEEDADMIN);
    ErrHandler.SysErrMsg();
    ErrHandler.SetErrorCode(RARX_CREATE);

    if (hd->Dir)
      RemoveDirectory(Name);
    else
      DeleteFile(Name);
    return false;
  }
  File LinkFile;
  LinkFile.SetHandle(hFile);
  LinkFile.SetOpenFileTime(
    Cmd->xmtime==EXTTIME_NONE ? NULL:&hd->mtime,
    Cmd->xctime==EXTTIME_NONE ? NULL:&hd->ctime,
    Cmd->xatime==EXTTIME_NONE ? NULL:&hd->atime);
  LinkFile.Close();
#ifndef NOFILECREATE
  if (!Cmd->IgnoreGeneralAttr)
    SetFileAttr(Name,hd->FileAttr);
#endif
  return true;
}
Beispiel #22
0
String VarFilePath() {
	String p = varsname;
	if(IsFullPath(varsname))
		return varsname;
	return VarFilePath(GetVarsName());
}