This repository has been archived on 2024-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
deb-goldedplus/goldlib/gall/gfilutl2.cpp
2009-11-29 12:20:28 +00:00

281 lines
7.6 KiB
C++

// This may look like C code, but it is really -*- C++ -*-
// ------------------------------------------------------------------
// The Goldware Library
// Copyright (C) 1990-1999 Odinn Sorensen
// Copyright (C) 1999-2000 Alexander S. Aganichev
// ------------------------------------------------------------------
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this program; if not, write to the Free
// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
// MA 02111-1307, USA
// ------------------------------------------------------------------
// $Id$
// ------------------------------------------------------------------
// File utility functions
// ------------------------------------------------------------------
#include <gfilutil.h>
#ifndef __HAVE_DRIVES__
#include <pwd.h>
#endif
#ifdef __WIN32__
#include <windows.h>
#endif
#include <stdlib.h>
#include <string.h>
// ------------------------------------------------------------------
// Adds the directory-delimiter character into end of string ('\\' in DOS-based, '/' in unix-based OS)
std::string& AddBackslash(std::string& p) {
for(size_t posn = 0; (posn=p.find(GOLD_WRONG_SLASH_CHR, posn)) != p.npos; posn++)
p[posn] = GOLD_SLASH_CHR;
if(p[p.length()-1] != GOLD_SLASH_CHR)
p += GOLD_SLASH_STR;
return p;
}
// ------------------------------------------------------------------
// Add path to filename, if no path is set. Don't chech size of 'path', be careful!
void MakePathname(std::string& pathname, const std::string& path, const std::string& name) {
Path pn;
MakePathname(pn, path.c_str(), name.c_str());
pathname = pn;
}
// ------------------------------------------------------------------
// Copy pathname with enviroment variables substitution and adds directory delimiter char.
// Copy not more sizeof(Path) characters (__dst should be type "Path" or equvalence, size is GMAXPATH)
void PathCopy(std::string& dst, const char* src) {
dst = src;
strschg_environ(dst);
AddBackslash(dst);
}
// ------------------------------------------------------------------
// DOS-style enviroment variables substitution in string.
int strschg_environ(std::string& s) {
std::string fnd;
int replaced = 0;
size_t posn, posn1;
while(((posn=s.find('%')) != s.npos) and ((posn1=s.find('%', posn+1)) != s.npos)) {
fnd = s.substr(posn+1, posn1-1-posn);
const char* rep = getenv(fnd.c_str());
rep = rep ? rep : "";
s.replace(posn, posn1-posn+1, rep);
replaced++;
}
#ifndef __HAVE_DRIVES__
if(not s.empty() and (s[0] == '~')) {
std::string name;
const char *p = s.c_str()+1;
struct passwd *pe=NULL;
if((s.length() != 1) and not isslash(*p)) {
while(*p and not isslash(*p))
name += *p++;
pe = getpwnam(name.c_str());
}
else {
pe = getpwuid(getuid());
}
if(pe != NULL) {
std::string dirname = pe->pw_dir;
dirname += "/";
if(isslash(*p))
++p;
dirname += p;
s = dirname.c_str();
replaced++;
}
}
#endif
return replaced;
}
// ------------------------------------------------------------------
// Change dirname to real full pathname
bool maketruepath(std::string &dirname) {
bool ok = true;
std::string ndirname;
char cwd[GMAXPATH];
getcwd(cwd, GMAXPATH);
#ifdef __HAVE_DRIVES__
#ifdef __WIN32__
char expanded[GMAXPATH];
char *k;
if(GetFullPathName(dirname.c_str(), GMAXPATH, expanded, &k) == 0) {
dirname = cwd;
ok = false;
}
else {
if(access(expanded, R_OK) == 0)
dirname = expanded;
else {
dirname = cwd;
ok = false;
}
}
#elif defined __OS2__
char expanded[GMAXPATH];
if(_fullpath(expanded, dirname.c_str(), GMAXPATH) == 0) {
if(access(expanded, R_OK) == 0)
dirname = expanded;
else {
dirname = cwd;
ok = false;
}
}
else {
dirname = cwd;
ok = false;
}
#elif defined __DJGPP__
char expanded[GMAXPATH];
_fixpath(dirname.c_str(), expanded);
if(access(expanded, R_OK) == 0)
dirname = expanded;
else {
dirname = cwd;
ok = false;
}
#else
long inspos = -1;
if((dirname.length() == 2) and (dirname[1] == ':'))
inspos = 2;
else if((dirname.length() < 2) or (dirname[1] != ':') or isslash(dirname[0]))
inspos = 0;
else if(not isslash(dirname[2]))
inspos = 2;
if(inspos != -1) {
char chdrive[] = " :";
chdrive[0] = (inspos == 2) ? dirname[0] : cwd[0];
if(not chdir(chdrive)) {
char dwd[GMAXPATH];
getcwd(dwd, GMAXPATH);
if(isslash(dirname[0]))
ndirname = chdrive;
else {
ndirname = dwd;
ndirname += "/";
}
ndirname += dirname.c_str() + inspos;
dirname = ndirname;
} else {
dirname = cwd;
ok = false;
}
chdir(cwd);
}
#endif
#else
if(not dirname.empty() and (dirname[0] == '~')) {
char* lname;
const char *p = dirname.c_str()+1;
if((dirname.length() != 1) and not isslash(*p)) {
while(*p and not isslash(*p))
ndirname += *p++; // get user name
} else {
if ((lname = getlogin()) == NULL)
lname = getenv("LOGNAME");
ndirname = lname; // get current user name
}
struct passwd *pe = getpwnam(ndirname.c_str()); // get home
if(pe != NULL) {
ndirname = pe->pw_dir;
ndirname += "/";
if(isslash(*p))
++p;
ndirname += p;
dirname = ndirname;
} else {
dirname = cwd;
ok = false;
}
} else if(not dirname.empty() and not isslash(dirname[0])) {
ndirname = cwd;
ndirname += "/";
ndirname += dirname;
dirname = ndirname;
}
#endif
size_t posn;
for(posn = 0; (posn=dirname.find(GOLD_WRONG_SLASH_CHR, posn)) != dirname.npos; posn++)
dirname[posn] = GOLD_SLASH_CHR;
size_t skipfrom, skipto;
#ifdef __HAVE_DRIVES__ /* Prevent from destroying UNC names */
if(dirname.length() > 1) {
while((skipfrom=dirname.find("\\\\", 1)) != dirname.npos)
dirname.erase(skipfrom, 1);
}
#endif
size_t len = dirname.length();
#ifdef __HAVE_DRIVES__
while((len > 3) and isslash(dirname[--len]))
#else
while((len > 1) and isslash(dirname[--len]))
#endif
dirname.erase(len, 1);
if(access(dirname.c_str(), R_OK)) {
dirname = cwd;
ok = false;
}
#ifdef __HAVE_DRIVES__
if((dirname.length() > 2) and (dirname[0] == '\\') and (dirname[1] == '\\'))
posn = 2;
else
#endif
posn = 0;
for(; (posn=dirname.find('\\', posn)) != dirname.npos; posn++)
dirname[posn] = '/';
while((skipto=dirname.find("/../")) != dirname.npos) {
skipfrom = (skipto == 0) ? 0 : dirname.rfind('/', skipto-1);
skipto += 2;
dirname.erase(skipfrom, skipto-skipfrom+1);
}
while((skipfrom=dirname.find("/./")) != dirname.npos)
dirname.erase(skipfrom, 2);
len = dirname.length();
if(len > 2 and not strcmp(&(dirname.c_str()[len-2]), "/."))
dirname.erase(len-2, 2);
len = dirname.length();
#ifdef __HAVE_DRIVES__
if((len > 3) and isslash(dirname[--len]))
#else
if((len > 1) and isslash(dirname[--len]))
#endif
dirname.erase(len, 1);
return ok;
}
// ------------------------------------------------------------------