mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-06-26 10:54:26 +02:00
Enhancement - Path, File, Directory integration
- Replaced all access calls. - Replaced all stat calls. - Obsoleted util.cpp isAbsoluteDirectory calls. - Obsoleted util.cpp expandPath calls.
This commit is contained in:
parent
8e47342a18
commit
b596e96b43
9 changed files with 66 additions and 120 deletions
|
@ -33,7 +33,7 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include "Path.h"
|
#include "Directory.h"
|
||||||
#include "File.h"
|
#include "File.h"
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include "text.h"
|
#include "text.h"
|
||||||
|
@ -354,9 +354,9 @@ void Config::createDefaultRC (const std::string& rc, const std::string& data)
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void Config::createDefaultData (const std::string& data)
|
void Config::createDefaultData (const std::string& data)
|
||||||
{
|
{
|
||||||
Path p (data);
|
Directory d (data);
|
||||||
if (! p.exists ())
|
if (! d.exists ())
|
||||||
mkdir (data.c_str (), S_IRWXU);
|
d.create ();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -32,6 +32,8 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include "Context.h"
|
#include "Context.h"
|
||||||
|
#include "Directory.h"
|
||||||
|
#include "File.h"
|
||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
#include "text.h"
|
#include "text.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
@ -107,7 +109,7 @@ void Context::initialize ()
|
||||||
|
|
||||||
// Load appropriate stringtable as soon after the config file as possible, to
|
// Load appropriate stringtable as soon after the config file as possible, to
|
||||||
// allow all subsequent messages to be localizable.
|
// allow all subsequent messages to be localizable.
|
||||||
std::string location = expandPath (config.get ("data.location"));
|
Directory location (config.get ("data.location"));
|
||||||
std::string locale = config.get ("locale");
|
std::string locale = config.get ("locale");
|
||||||
|
|
||||||
// If there is a locale variant (en-US.<variant>), then strip it.
|
// If there is a locale variant (en-US.<variant>), then strip it.
|
||||||
|
@ -116,16 +118,16 @@ void Context::initialize ()
|
||||||
locale = locale.substr (0, period);
|
locale = locale.substr (0, period);
|
||||||
|
|
||||||
if (locale != "")
|
if (locale != "")
|
||||||
stringtable.load (location + "/strings." + locale);
|
stringtable.load (location.data + "/strings." + locale);
|
||||||
|
|
||||||
// TODO Handle "--version, -v" right here?
|
// TODO Handle "--version, -v" right here?
|
||||||
|
|
||||||
// init TDB.
|
// init TDB.
|
||||||
tdb.clear ();
|
tdb.clear ();
|
||||||
std::vector <std::string> all;
|
std::vector <std::string> all;
|
||||||
split (all, location, ',');
|
split (all, location.data, ',');
|
||||||
foreach (path, all)
|
foreach (path, all)
|
||||||
tdb.location (expandPath (*path));
|
tdb.location (*path);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -244,8 +246,8 @@ int Context::dispatch (std::string &out)
|
||||||
void Context::shadow ()
|
void Context::shadow ()
|
||||||
{
|
{
|
||||||
// Determine if shadow file is enabled.
|
// Determine if shadow file is enabled.
|
||||||
std::string shadowFile = expandPath (config.get ("shadow.file"));
|
File shadowFile (config.get ("shadow.file"));
|
||||||
if (shadowFile != "")
|
if (shadowFile.data != "")
|
||||||
{
|
{
|
||||||
inShadow = true; // Prevents recursion in case shadow command writes.
|
inShadow = true; // Prevents recursion in case shadow command writes.
|
||||||
|
|
||||||
|
@ -281,21 +283,21 @@ void Context::shadow ()
|
||||||
parse ();
|
parse ();
|
||||||
std::string result;
|
std::string result;
|
||||||
(void)dispatch (result);
|
(void)dispatch (result);
|
||||||
std::ofstream out (shadowFile.c_str ());
|
std::ofstream out (shadowFile.data.c_str ());
|
||||||
if (out.good ())
|
if (out.good ())
|
||||||
{
|
{
|
||||||
out << result;
|
out << result;
|
||||||
out.close ();
|
out.close ();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw std::string ("Could not write file '") + shadowFile + "'";
|
throw std::string ("Could not write file '") + shadowFile.data + "'";
|
||||||
|
|
||||||
config.set ("curses", oldCurses);
|
config.set ("curses", oldCurses);
|
||||||
config.set ("color", oldColor);
|
config.set ("color", oldColor);
|
||||||
|
|
||||||
// Optionally display a notification that the shadow file was updated.
|
// Optionally display a notification that the shadow file was updated.
|
||||||
if (config.getBoolean ("shadow.notify"))
|
if (config.getBoolean ("shadow.notify"))
|
||||||
footnote (std::string ("[Shadow file '") + shadowFile + "' updated]");
|
footnote (std::string ("[Shadow file '") + shadowFile.data + "' updated]");
|
||||||
|
|
||||||
inShadow = false;
|
inShadow = false;
|
||||||
}
|
}
|
||||||
|
@ -355,8 +357,10 @@ void Context::loadCorrectConfigFile ()
|
||||||
"Could not read home directory from the passwd file."));
|
"Could not read home directory from the passwd file."));
|
||||||
|
|
||||||
std::string home = pw->pw_dir;
|
std::string home = pw->pw_dir;
|
||||||
std::string rc = home + "/.taskrc";
|
// std::string rc = home + "/.taskrc";
|
||||||
std::string data = home + "/.task";
|
// std::string data = home + "/.task";
|
||||||
|
File rc (home + "/.taskrc");
|
||||||
|
Directory data (home + "./task");
|
||||||
|
|
||||||
// Is there an file_override for rc:?
|
// Is there an file_override for rc:?
|
||||||
foreach (arg, args)
|
foreach (arg, args)
|
||||||
|
@ -366,17 +370,17 @@ void Context::loadCorrectConfigFile ()
|
||||||
else if (arg->substr (0, 3) == "rc:")
|
else if (arg->substr (0, 3) == "rc:")
|
||||||
{
|
{
|
||||||
file_override = *arg;
|
file_override = *arg;
|
||||||
rc = arg->substr (3);
|
rc = File (arg->substr (3));
|
||||||
|
|
||||||
home = rc;
|
home = rc.data;
|
||||||
std::string::size_type last_slash = rc.rfind ("/");
|
std::string::size_type last_slash = rc.data.rfind ("/");
|
||||||
if (last_slash != std::string::npos)
|
if (last_slash != std::string::npos)
|
||||||
home = rc.substr (0, last_slash);
|
home = rc.data.substr (0, last_slash);
|
||||||
else
|
else
|
||||||
home = ".";
|
home = ".";
|
||||||
|
|
||||||
args.erase (arg);
|
args.erase (arg);
|
||||||
header ("Using alternate .taskrc file " + rc); // TODO i18n
|
header ("Using alternate .taskrc file " + rc.data); // TODO i18n
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -384,10 +388,10 @@ void Context::loadCorrectConfigFile ()
|
||||||
// Load rc file.
|
// Load rc file.
|
||||||
config.clear (); // Dump current values.
|
config.clear (); // Dump current values.
|
||||||
config.setDefaults (); // Add in the custom reports.
|
config.setDefaults (); // Add in the custom reports.
|
||||||
config.load (rc); // Load new file.
|
config.load (rc.data); // Load new file.
|
||||||
|
|
||||||
if (config.get ("data.location") != "")
|
if (config.get ("data.location") != "")
|
||||||
data = config.get ("data.location");
|
data = Directory (config.get ("data.location"));
|
||||||
|
|
||||||
// Are there any var_overrides for data.location?
|
// Are there any var_overrides for data.location?
|
||||||
foreach (arg, args)
|
foreach (arg, args)
|
||||||
|
@ -397,35 +401,35 @@ void Context::loadCorrectConfigFile ()
|
||||||
else if (arg->substr (0, 17) == "rc.data.location:" ||
|
else if (arg->substr (0, 17) == "rc.data.location:" ||
|
||||||
arg->substr (0, 17) == "rc.data.location=")
|
arg->substr (0, 17) == "rc.data.location=")
|
||||||
{
|
{
|
||||||
data = arg->substr (17);
|
data = Directory (arg->substr (17));
|
||||||
header ("Using alternate data.location " + data); // TODO i18n
|
header ("Using alternate data.location " + data.data); // TODO i18n
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do we need to create a default rc?
|
// Do we need to create a default rc?
|
||||||
if (access (rc.c_str (), F_OK))
|
if (! rc.exists ())
|
||||||
{
|
{
|
||||||
if (confirm ("A configuration file could not be found in " // TODO i18n
|
if (confirm ("A configuration file could not be found in " // TODO i18n
|
||||||
+ home
|
+ home
|
||||||
+ "\n\n"
|
+ "\n\n"
|
||||||
+ "Would you like a sample "
|
+ "Would you like a sample "
|
||||||
+ rc
|
+ rc.data
|
||||||
+ " created, so task can proceed?"))
|
+ " created, so task can proceed?"))
|
||||||
{
|
{
|
||||||
config.createDefaultRC (rc, data);
|
config.createDefaultRC (rc.data, data.data);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw std::string ("Cannot proceed without rc file.");
|
throw std::string ("Cannot proceed without rc file.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create data location, if necessary.
|
// Create data location, if necessary.
|
||||||
config.createDefaultData (data);
|
config.createDefaultData (data.data);
|
||||||
|
|
||||||
// Load rc file.
|
// Load rc file.
|
||||||
config.clear (); // Dump current values.
|
config.clear (); // Dump current values.
|
||||||
config.setDefaults (); // Add in the custom reports.
|
config.setDefaults (); // Add in the custom reports.
|
||||||
config.load (rc); // Load new file.
|
config.load (rc.data); // Load new file.
|
||||||
|
|
||||||
// Apply overrides of type: "rc.name:value", or "rc.name=value".
|
// Apply overrides of type: "rc.name:value", or "rc.name=value".
|
||||||
std::vector <std::string> filtered;
|
std::vector <std::string> filtered;
|
||||||
|
|
23
src/TDB.cpp
23
src/TDB.cpp
|
@ -35,6 +35,7 @@
|
||||||
#include "text.h"
|
#include "text.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "TDB.h"
|
#include "TDB.h"
|
||||||
|
#include "Directory.h"
|
||||||
#include "Table.h"
|
#include "Table.h"
|
||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
#include "Color.h"
|
#include "Color.h"
|
||||||
|
@ -107,12 +108,13 @@ void TDB::clear ()
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void TDB::location (const std::string& path)
|
void TDB::location (const std::string& path)
|
||||||
{
|
{
|
||||||
if (access (expandPath (path).c_str (), F_OK))
|
Directory d (path);
|
||||||
|
if (!d.exists ())
|
||||||
throw std::string ("Data location '") +
|
throw std::string ("Data location '") +
|
||||||
path +
|
path +
|
||||||
"' does not exist, or is not readable and writable.";
|
"' does not exist, or is not readable and writable.";
|
||||||
|
|
||||||
mLocations.push_back (Location (path));
|
mLocations.push_back (Location (d.data));
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -503,11 +505,11 @@ int TDB::nextId ()
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void TDB::undo ()
|
void TDB::undo ()
|
||||||
{
|
{
|
||||||
std::string location = expandPath (context.config.get ("data.location"));
|
Directory location (context.config.get ("data.location"));
|
||||||
|
|
||||||
std::string undoFile = location + "/undo.data";
|
std::string undoFile = location.data + "/undo.data";
|
||||||
std::string pendingFile = location + "/pending.data";
|
std::string pendingFile = location.data + "/pending.data";
|
||||||
std::string completedFile = location + "/completed.data";
|
std::string completedFile = location.data + "/completed.data";
|
||||||
|
|
||||||
// load undo.data
|
// load undo.data
|
||||||
std::vector <std::string> u;
|
std::vector <std::string> u;
|
||||||
|
@ -725,9 +727,10 @@ FILE* TDB::openAndLock (const std::string& file)
|
||||||
// TODO Need provision here for read-only locations.
|
// TODO Need provision here for read-only locations.
|
||||||
|
|
||||||
// Check for access.
|
// Check for access.
|
||||||
bool exists = access (file.c_str (), F_OK) ? false : true;
|
File f (file);
|
||||||
|
bool exists = f.exists ();
|
||||||
if (exists)
|
if (exists)
|
||||||
if (access (file.c_str (), R_OK | W_OK))
|
if (!f.readable () || !f.writable ())
|
||||||
throw std::string ("Task does not have the correct permissions for '") +
|
throw std::string ("Task does not have the correct permissions for '") +
|
||||||
file + "'.";
|
file + "'.";
|
||||||
|
|
||||||
|
@ -755,8 +758,6 @@ FILE* TDB::openAndLock (const std::string& file)
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void TDB::writeUndo (const Task& after, FILE* file)
|
void TDB::writeUndo (const Task& after, FILE* file)
|
||||||
{
|
{
|
||||||
Timer t ("TDB::writeUndo");
|
|
||||||
|
|
||||||
fprintf (file,
|
fprintf (file,
|
||||||
"time %u\nnew %s---\n",
|
"time %u\nnew %s---\n",
|
||||||
(unsigned int) time (NULL),
|
(unsigned int) time (NULL),
|
||||||
|
@ -766,8 +767,6 @@ void TDB::writeUndo (const Task& after, FILE* file)
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void TDB::writeUndo (const Task& before, const Task& after, FILE* file)
|
void TDB::writeUndo (const Task& before, const Task& after, FILE* file)
|
||||||
{
|
{
|
||||||
Timer t ("TDB::writeUndo");
|
|
||||||
|
|
||||||
fprintf (file,
|
fprintf (file,
|
||||||
"time %u\nold %snew %s---\n",
|
"time %u\nold %snew %s---\n",
|
||||||
(unsigned int) time (NULL),
|
(unsigned int) time (NULL),
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include "Permission.h"
|
#include "Permission.h"
|
||||||
|
#include "Directory.h"
|
||||||
#include "text.h"
|
#include "text.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
@ -619,12 +620,14 @@ int handleConfig (std::string &outs)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (context.config.get ("data.location") == "")
|
Directory location (context.config.get ("data.location"));
|
||||||
|
|
||||||
|
if (location.data == "")
|
||||||
out << "Configuration error: data.location not specified in .taskrc "
|
out << "Configuration error: data.location not specified in .taskrc "
|
||||||
"file."
|
"file."
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
if (access (expandPath (context.config.get ("data.location")).c_str (), X_OK))
|
if (! location.exists ())
|
||||||
out << "Configuration error: data.location contains a directory name"
|
out << "Configuration error: data.location contains a directory name"
|
||||||
" that doesn't exist, or is unreadable."
|
" that doesn't exist, or is unreadable."
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include "Directory.h"
|
||||||
#include "Date.h"
|
#include "Date.h"
|
||||||
#include "Duration.h"
|
#include "Duration.h"
|
||||||
#include "text.h"
|
#include "text.h"
|
||||||
|
@ -521,13 +522,13 @@ static void parseTask (Task& task, const std::string& after)
|
||||||
void editFile (Task& task)
|
void editFile (Task& task)
|
||||||
{
|
{
|
||||||
// Check for file permissions.
|
// Check for file permissions.
|
||||||
std::string dataLocation = expandPath (context.config.get ("data.location"));
|
Directory location (context.config.get ("data.location"));
|
||||||
if (access (dataLocation.c_str (), X_OK))
|
if (! location.writable ())
|
||||||
throw std::string ("Your data.location directory is not writable.");
|
throw std::string ("Your data.location directory is not writable.");
|
||||||
|
|
||||||
// Create a temp file name in data.location.
|
// Create a temp file name in data.location.
|
||||||
std::stringstream file;
|
std::stringstream file;
|
||||||
file << dataLocation << "/task." << getpid () << "." << task.id << ".task";
|
file << location.data << "/task." << getpid () << "." << task.id << ".task";
|
||||||
|
|
||||||
// Format the contents, T -> text, write to a file.
|
// Format the contents, T -> text, write to a file.
|
||||||
std::string before = formatTask (task);
|
std::string before = formatTask (task);
|
||||||
|
|
|
@ -29,7 +29,6 @@
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -37,6 +36,8 @@
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include "Context.h"
|
#include "Context.h"
|
||||||
|
#include "Directory.h"
|
||||||
|
#include "File.h"
|
||||||
#include "Date.h"
|
#include "Date.h"
|
||||||
#include "Table.h"
|
#include "Table.h"
|
||||||
#include "text.h"
|
#include "text.h"
|
||||||
|
@ -1716,24 +1717,20 @@ int handleReportStats (std::string &outs)
|
||||||
// Go get the file sizes.
|
// Go get the file sizes.
|
||||||
size_t dataSize = 0;
|
size_t dataSize = 0;
|
||||||
|
|
||||||
struct stat s;
|
Directory location (context.config.get ("data.location"));
|
||||||
std::string location = expandPath (context.config.get ("data.location"));
|
File pending (location.data + "/pending.data");
|
||||||
std::string file = location + "/pending.data";
|
dataSize += pending.size ();
|
||||||
if (!stat (file.c_str (), &s))
|
|
||||||
dataSize += s.st_size;
|
|
||||||
|
|
||||||
file = location + "/completed.data";
|
File completed (location.data + "/completed.data");
|
||||||
if (!stat (file.c_str (), &s))
|
dataSize += completed.size ();
|
||||||
dataSize += s.st_size;
|
|
||||||
|
|
||||||
file = location + "/undo.data";
|
File undo (location.data + "/undo.data");
|
||||||
if (!stat (file.c_str (), &s))
|
dataSize += undo.size ();
|
||||||
dataSize += s.st_size;
|
|
||||||
|
|
||||||
std::vector <std::string> undo;
|
std::vector <std::string> undoTxns;
|
||||||
slurp (file, undo, false);
|
slurp (undo.data, undoTxns, false);
|
||||||
int undoCount = 0;
|
int undoCount = 0;
|
||||||
foreach (tx, undo)
|
foreach (tx, undoTxns)
|
||||||
if (tx->substr (0, 3) == "---")
|
if (tx->substr (0, 3) == "---")
|
||||||
++undoCount;
|
++undoCount;
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ Context context;
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
int main (int argc, char** argv)
|
int main (int argc, char** argv)
|
||||||
{
|
{
|
||||||
UnitTest t (439);
|
UnitTest t (430);
|
||||||
|
|
||||||
// TODO bool confirm (const std::string&);
|
// TODO bool confirm (const std::string&);
|
||||||
// TODO int confirm3 (const std::string&);
|
// TODO int confirm3 (const std::string&);
|
||||||
|
@ -514,19 +514,6 @@ int main (int argc, char** argv)
|
||||||
|
|
||||||
// TODO const std::string uuid ();
|
// TODO const std::string uuid ();
|
||||||
|
|
||||||
// std::string expandPath (const std::string&);
|
|
||||||
t.ok (expandPath ("foo") == "foo", "expandPath nop");
|
|
||||||
t.ok (expandPath ("~/") != "~/", "expandPath ~/");
|
|
||||||
t.ok (expandPath ("~") != "~", "expandPath ~");
|
|
||||||
|
|
||||||
// bool isAbsolutePath (const std::string&);
|
|
||||||
t.notok (isAbsolutePath ("."), "isAbsolutePath .");
|
|
||||||
t.notok (isAbsolutePath ("~"), "isAbsolutePath ~");
|
|
||||||
t.ok (isAbsolutePath (expandPath ("~")), "isAbsolutePath (expandPath ~)");
|
|
||||||
t.ok (isAbsolutePath (expandPath ("~/")), "isAbsolutePath (expandPath ~/)");
|
|
||||||
t.ok (isAbsolutePath ("/"), "isAbsolutePath /");
|
|
||||||
t.ok (isAbsolutePath ("/tmp"), "isAbsolutePath /tmp");
|
|
||||||
|
|
||||||
// TODO bool slurp (const std::string&, std::vector <std::string>&, bool trimLines = false);
|
// TODO bool slurp (const std::string&, std::vector <std::string>&, bool trimLines = false);
|
||||||
// TODO bool slurp (const std::string&, std::string&, bool trimLines = false);
|
// TODO bool slurp (const std::string&, std::string&, bool trimLines = false);
|
||||||
// TODO void spit (const std::string&, const std::string&);
|
// TODO void spit (const std::string&, const std::string&);
|
||||||
|
|
43
src/util.cpp
43
src/util.cpp
|
@ -341,49 +341,6 @@ const std::string uuid ()
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// no i18n
|
|
||||||
std::string expandPath (const std::string& in)
|
|
||||||
{
|
|
||||||
std::string copy = in;
|
|
||||||
std::string::size_type tilde;
|
|
||||||
|
|
||||||
if ((tilde = copy.find ("~/")) != std::string::npos)
|
|
||||||
{
|
|
||||||
struct passwd* pw = getpwuid (getuid ());
|
|
||||||
copy.replace (tilde, 1, pw->pw_dir);
|
|
||||||
}
|
|
||||||
else if ((tilde = copy.find ("~")) != std::string::npos)
|
|
||||||
{
|
|
||||||
struct passwd* pw = getpwuid (getuid ());
|
|
||||||
std::string home = pw->pw_dir;
|
|
||||||
home += "/";
|
|
||||||
copy.replace (tilde, 1, home);
|
|
||||||
}
|
|
||||||
else if ((tilde = copy.find ("~")) != std::string::npos)
|
|
||||||
{
|
|
||||||
std::string::size_type slash;
|
|
||||||
if ((slash = copy.find ("/", tilde)) != std::string::npos)
|
|
||||||
{
|
|
||||||
std::string name = copy.substr (tilde + 1, slash - tilde - 1);
|
|
||||||
struct passwd* pw = getpwnam (name.c_str ());
|
|
||||||
if (pw)
|
|
||||||
copy.replace (tilde, slash - tilde, pw->pw_dir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return copy;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
bool isAbsolutePath (const std::string& in)
|
|
||||||
{
|
|
||||||
if (in.length () && in[0] == '/')
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// On Solaris no flock function exists.
|
// On Solaris no flock function exists.
|
||||||
#ifdef SOLARIS
|
#ifdef SOLARIS
|
||||||
|
|
|
@ -60,8 +60,6 @@ std::string formatSecondsCompact (time_t);
|
||||||
std::string formatBytes (size_t);
|
std::string formatBytes (size_t);
|
||||||
int autoComplete (const std::string&, const std::vector<std::string>&, std::vector<std::string>&);
|
int autoComplete (const std::string&, const std::vector<std::string>&, std::vector<std::string>&);
|
||||||
const std::string uuid ();
|
const std::string uuid ();
|
||||||
std::string expandPath (const std::string&);
|
|
||||||
bool isAbsolutePath (const std::string&);
|
|
||||||
|
|
||||||
#ifdef SOLARIS
|
#ifdef SOLARIS
|
||||||
#define LOCK_SH 1
|
#define LOCK_SH 1
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue