diff --git a/src/libstore/db.cc b/src/libstore/db.cc index d624c9c25..3d05e1786 100644 --- a/src/libstore/db.cc +++ b/src/libstore/db.cc @@ -541,7 +541,7 @@ bool Database::revisionToTimeStamp(const Transaction & txn, TableId revisions_ta void Database::setStateReferences(const Transaction & txn, TableId references_table, TableId revisions_table, const Path & statePath, const Strings & references, int revision, int timestamp) { - //printMsg(lvlError, format("setStateReferences/Referrers %1%") % table); + //printMsg(lvlError, format("setStateReferences '%1%' for '%2%'") % references_table % statePath); if(revision == -1 && timestamp == -1) timestamp = getTimeStamp(); @@ -556,13 +556,13 @@ void Database::setStateReferences(const Transaction & txn, TableId references_ta //Warning if it already exists Strings empty; - if( queryStateReferences(txn, references_table, revisions_table, statePath, empty, -1, timestamp) ) - printMsg(lvlError, format("Warning: The timestamp '%1%' already exists for set-references/referrers of path '%2%' with db '%3%'") % timestamp % statePath % references_table); + if( queryStrings(txn, references_table, mergeToDBKey(statePath, timestamp), empty) ) + printMsg(lvlError, format("Warning: The timestamp '%1%' (now: '%5%') / revision '%4%' already exists for set-references of path '%2%' with db '%3%'") + % timestamp % statePath % references_table % revision % getTimeStamp()); //Create the key string key = mergeToDBKey(statePath, timestamp); - - + //printMsg(lvlError, format("Set references '%1%'") % key); //for (Strings::const_iterator i = references.begin(); i != references.end(); ++i) // printMsg(lvlError, format("reference '%1%'") % *i); @@ -574,14 +574,14 @@ void Database::setStateReferences(const Transaction & txn, TableId references_ta bool Database::queryStateReferences(const Transaction & txn, TableId references_table, TableId revisions_table, const Path & statePath, Strings & references, int revision, int timestamp) { - //printMsg(lvlError, format("queryStateReferences/Referrers '%1%' with revision '%2%'") % references_table % revision); + //printMsg(lvlError, format("queryStateReferences '%1%' with revision '%2%'") % references_table % revision); //Convert revision to timestamp number useing the revisions_table if(timestamp == -1 && revision != -1){ bool found = revisionToTimeStamp(txn, revisions_table, statePath, revision, timestamp); if(!found) //we are asked for references of some revision, but there are no references registered yet, so we return false; return false; - } + } Strings keys; enumTable(txn, references_table, keys); diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index 68c2c9011..4c0b5917c 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -992,7 +992,7 @@ static void setHash(const Transaction & txn, const Path & storePath, const Hash static void setStateValid(const Transaction & txn, const Path & statePath, const Path & drvPath) { - printMsg(lvlError, format("setStateValid: '%1%' '%2%'") % statePath % drvPath); + //printMsg(lvlError, format("Setting statetpath as a valid path in dbValidStatePaths '%1%' with drv '%2%'") % statePath % drvPath); nixDB.setString(txn, dbValidStatePaths, statePath, drvPath); } diff --git a/src/libutil/util.cc b/src/libutil/util.cc index deea519a3..65dd0ad3f 100644 --- a/src/libutil/util.cc +++ b/src/libutil/util.cc @@ -18,7 +18,6 @@ #include #include - extern char * * environ; @@ -1152,11 +1151,23 @@ bool FileExist(const string FileName) { const char* FileName_C = FileName.c_str(); struct stat my_stat; - return (stat(FileName_C, &my_stat) == 0); + if (stat(FileName_C, &my_stat) != 0) return false; + return ((my_stat.st_mode & S_IFREG) != 0); + + /* + S_IFMT 0170000 bitmask for the file type bitfields + S_IFSOCK 0140000 socket + S_IFLNK 0120000 symbolic link + S_IFREG 0100000 regular file + S_IFBLK 0060000 block device + S_IFDIR 0040000 directory + S_IFCHR 0020000 character device + S_IFIFO 0010000 fifo + */ } //TODO Does this work on windows? -bool IsDirectory(const string FileName) //TODO Use pathExists?? +bool IsDirectory(const string FileName) { const char* FileName_C = FileName.c_str(); struct stat my_stat; diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 41868757a..ac6121b5b 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -36,9 +36,16 @@ Path dirOf(const Path & path); following the final `/'. */ string baseNameOf(const Path & path); -/* Return true iff the given path exists. */ +/* Return true if the given path (dir of file) exists. */ bool pathExists(const Path & path); +/* Return true if the given file exists. */ +bool FileExist(const string FileName); + +/* Return true if the given dir exists. */ +bool IsDirectory(const string FileName); + + /* Read the contents (target) of a symbolic link. The result is not in any way canonicalised. */ Path readLink(const Path & path); @@ -303,10 +310,6 @@ void runProgram_AndPrintOutput(Path program, bool searchPath, const Strings & ar int getTimeStamp(); -bool FileExist(const string FileName); - -bool IsDirectory(const string FileName); //TODO replace by pathexists - string getCallingUserName(); /* TODO */ diff --git a/src/nix-state/nix-state.cc b/src/nix-state/nix-state.cc index b40c8bdac..da5640c2a 100644 --- a/src/nix-state/nix-state.cc +++ b/src/nix-state/nix-state.cc @@ -50,17 +50,14 @@ Derivation getDerivation(const string & fullPath, const string & program_args, s bool getDerivers, PathSet & derivers) //optional { //Parse the full path like /nix/store/...../bin/hello - //string fullPath = opArgs.front(); - componentPath = fullPath.substr(nixStore.size() + 1, fullPath.size()); //+1 to strip off the / int pos = componentPath.find("/",0); componentPath = fullPath.substr(0, pos + nixStore.size() + 1); binary = fullPath.substr(pos + nixStore.size() + 1, fullPath.size()); - //TODO REAL CHECK for validity of componentPath ... ? sometimes, indentifier can be excluded - if(componentPath == "/nix/store") - throw UsageError("You must specify the full! binary path"); - + if( ! (store->isValidPath(componentPath) || store->isValidStatePath(componentPath)) ) + throw UsageError(format("Path '%1%' is not a valid state or store path") % componentPath); + //Check if path is statepath isStateComponent = store->isStateComponent(componentPath); @@ -158,27 +155,6 @@ static void opShowStatePath(Strings opFlags, Strings opArgs) printMsg(lvlError, format("%1%") % statePath); } -//Prints the root path that contains the repoisitorys of the state of a component - indetiefier combination -static void opShowStatePathAtRevision(Strings opFlags, Strings opArgs) -{ - Path componentPath; - Path statePath; - string binary; - string derivationPath; - bool isStateComponent; - string program_args; - Derivation drv = getDerivation_andCheckArgs(opFlags, opArgs, componentPath, statePath, binary, derivationPath, isStateComponent, program_args); - - if(!isStateComponent) - throw UsageError(format("This path '%1%' is not a state-component path") % componentPath); - - //TODO - - //printMsg(lvlError, format("%1%") % repos); -} - - - /* * Input: store (or statePath?) * Returns all the drv's of the statePaths (in)directly referenced. @@ -221,10 +197,11 @@ static void queryAvailableStateRevisions(Strings opFlags, Strings opArgs) for (RevisionNumbers::iterator i = revisions.begin(); i != revisions.end(); ++i) revisions_sort.push_back(*i); sort(revisions_sort.begin(), revisions_sort.end()); - string revisions_txt=""; + for (vector::iterator i = revisions_sort.begin(); i != revisions_sort.end(); ++i) - revisions_txt += int2String(*i) + " "; - printMsg(lvlError, format("Available Revisions: %1%") % revisions_txt); + printMsg(lvlError, format("Available Revision: %1% with date .....") % *i); + + } static void revertToRevision(Strings opFlags, Strings opArgs) @@ -323,7 +300,7 @@ static void revertToRevision(Strings opFlags, Strings opArgs) printMsg(lvlError, format("Command: '%1%'") % cpcommand); cpcommand += " " + revertPathOrFile; p_args.push_back(cpcommand); - runProgram_AndPrintOutput("sh", true, p_args, "sh-cp"); //TODO does this work on windows? + runProgram_AndPrintOutput("sh", true, p_args, "sh-cp"); } @@ -408,10 +385,6 @@ void scanAndUpdateAllReferencesTxn(const Transaction & txn, const Path & statePa for (PathSet::iterator i = diff_state_references_removed.begin(); i != diff_state_references_removed.end(); ++i) printMsg(lvlError, format("Removed state reference found!: '%1%' in state path '%2%'") % (*i) % statePath); - //If any changes are detected: register the paths valid with a new revision number - //if(diff_references_added.size() != 0 || diff_references_removed.size() != 0 || - //diff_state_references_added.size() != 0 || diff_state_references_removed.size() != 0 ) - //We always set the referernces so we know they were scanned (maybe the same) at a certain time printMsg(lvlError, format("Updating new references for statepath: '%1%'") % statePath); Path drvPath = queryStatePathDrvTxn(txn, statePath); @@ -424,7 +397,7 @@ void scanAndUpdateAllReferencesTxn(const Transaction & txn, const Path & statePa -1); //Set at a new timestamp } -void scanAndUpdateAllReferencesRecusivelyTxn(const Transaction & txn, const Path & statePath) //TODO Can also work for statePaths??? +void scanAndUpdateAllReferencesRecusivelyTxn(const Transaction & txn, const Path & statePath) { if(! isValidStatePathTxn(txn, statePath)) throw Error(format("This path '%1%' is not a state path") % statePath); @@ -465,6 +438,7 @@ static void opRunComponent(Strings opFlags, Strings opArgs) string root_program_args; Derivation root_drv = getDerivation_andCheckArgs(opFlags, opArgs, root_componentPath, root_statePath, root_binary, root_derivationPath, root_isStateComponent, root_program_args); + //TODO //Check for locks ... ? or put locks on the neseccary state components //WARNING: we need to watch out for deadlocks! //add locks ... ? @@ -479,8 +453,12 @@ static void opRunComponent(Strings opFlags, Strings opArgs) //******************* Run **************************** - if(!only_commit) + if(!only_commit){ + if( ! FileExist(root_componentPath + root_binary) ) + throw Error(format("You must specify the full binary path: '%1%'") % (root_componentPath + root_binary)); + executeShellCommand(root_componentPath + root_binary + " " + root_program_args); + } //******************* Scan for new references if neccecary if(scanforReferences) @@ -641,8 +619,23 @@ void run(Strings args) printMsg(lvlError, format("NOW: '%1%'") % test["q"]); return; - */ + printMsg(lvlError, format("NOW: '%1%'") % pathExists("/etc") ); + printMsg(lvlError, format("NOW: '%1%'") % pathExists("/etc/passwd") ); + return; + + printMsg(lvlError, format("NOW: '%1%'") % FileExist("/nix/store/65c7p6c8j0vy6b8fjgq84zziiavswqha-hellohardcodedstateworld-1.0/") ); + printMsg(lvlError, format("NOW: '%1%'") % FileExist("/nix/store/65c7p6c8j0vy6b8fjgq84zziiavswqha-hellohardcodedstateworld-1.0/bin/hello") ); + printMsg(lvlError, format("NOW: '%1%'") % IsDirectory("/nix/store/65c7p6c8j0vy6b8fjgq84zziiavswqha-hellohardcodedstateworld-1.0/") ); + printMsg(lvlError, format("NOW: '%1%'") % IsDirectory("/nix/store/65c7p6c8j0vy6b8fjgq84zziiavswqha-hellohardcodedstateworld-1.0/bin/hello") ); + printMsg(lvlError, format("NOW: '%1%'") % FileExist("/nix/store/65c7p6c8j0vy6b8fjgq8") ); + printMsg(lvlError, format("NOW: '%1%'") % IsDirectory("/nix/store/65c7p6c8j0vy6b8fjg") ); + + return; + */ + + + /* test */ for (Strings::iterator i = args.begin(); i != args.end(); ) {