1 #include "store-api.hh"
11 GCOptions::GCOptions()
13 action
= gcDeleteDead
;
14 ignoreLiveness
= false;
15 maxFreed
= ULLONG_MAX
;
19 bool isInStore(const Path
& path
)
21 return isInDir(path
, settings
.nixStore
);
25 bool isStorePath(const Path
& path
)
27 return isInStore(path
)
28 && path
.find('/', settings
.nixStore
.size() + 1) == Path::npos
;
32 void assertStorePath(const Path
& path
)
34 if (!isStorePath(path
))
35 throw Error(format("path `%1%' is not in the Nix store") % path
);
39 Path
toStorePath(const Path
& path
)
42 throw Error(format("path `%1%' is not in the Nix store") % path
);
43 Path::size_type slash
= path
.find('/', settings
.nixStore
.size() + 1);
44 if (slash
== Path::npos
)
47 return Path(path
, 0, slash
);
51 Path
followLinksToStore(const Path
& _path
)
53 Path path
= absPath(_path
);
54 while (!isInStore(path
)) {
55 if (!isLink(path
)) break;
56 string target
= readLink(path
);
57 path
= absPath(target
, dirOf(path
));
60 throw Error(format("path `%1%' is not in the Nix store") % path
);
65 Path
followLinksToStorePath(const Path
& path
)
67 return toStorePath(followLinksToStore(path
));
71 string
storePathToName(const Path
& path
)
73 assertStorePath(path
);
74 return string(path
, settings
.nixStore
.size() + 34);
78 void checkStoreName(const string
& name
)
80 string validChars
= "+-._?=";
81 /* Disallow names starting with a dot for possible security
82 reasons (e.g., "." and ".."). */
83 if (string(name
, 0, 1) == ".")
84 throw Error(format("illegal name: `%1%'") % name
);
85 foreach (string::const_iterator
, i
, name
)
86 if (!((*i
>= 'A' && *i
<= 'Z') ||
87 (*i
>= 'a' && *i
<= 'z') ||
88 (*i
>= '0' && *i
<= '9') ||
89 validChars
.find(*i
) != string::npos
))
91 throw Error(format("invalid character `%1%' in name `%2%'")
97 /* Store paths have the following form:
103 <store> = the location of the Nix store, usually /nix/store
105 <name> = a human readable name for the path, typically obtained
106 from the name attribute of the derivation, or the name of the
107 source file from which the store path is created. For derivation
108 outputs other than the default "out" output, the string "-<id>"
109 is suffixed to <name>.
111 <h> = base-32 representation of the first 160 bits of a SHA-256
112 hash of <s>; the hash part of the store name
114 <s> = the string "<type>:sha256:<h2>:<store>:<name>";
115 note that it includes the location of the store as well as the
116 name to make sure that changes to either of those are reflected
117 in the hash (e.g. you won't get /nix/store/<h>-name1 and
118 /nix/store/<h>-name2 with equal hash parts).
121 "text:<r1>:<r2>:...<rN>"
122 for plain text files written to the store using
123 addTextToStore(); <r1> ... <rN> are the references of the
126 for paths copied to the store using addToStore() when recursive
127 = true and hashAlgo = "sha256"
129 for either the outputs created by derivations, OR paths copied
130 to the store using addToStore() with recursive != true or
131 hashAlgo != "sha256" (in that case "source" is used; it's
132 silly, but it's done that way for compatibility). <id> is the
133 name of the output (usually, "out").
135 <h2> = base-16 representation of a SHA-256 hash of:
136 if <type> = "text:...":
137 the string written to the resulting store path
138 if <type> = "source":
139 the serialisation of the path from which this store path is
140 copied, as returned by hashPath()
141 if <type> = "output:out":
142 for non-fixed derivation outputs:
143 the derivation (see hashDerivationModulo() in
145 for paths copied by addToStore() or produced by fixed-output
147 the string "fixed:out:<rec><algo>:<hash>:", where
148 <rec> = "r:" for recursive (path) hashes, or "" or flat
150 <algo> = "md5", "sha1" or "sha256"
151 <hash> = base-16 representation of the path or flat hash of
152 the contents of the path (or expected contents of the
153 path for fixed-output derivations)
155 It would have been nicer to handle fixed-output derivations under
156 "source", e.g. have something like "source:<rec><algo>", but we're
157 stuck with this for now...
159 The main reason for this way of computing names is to prevent name
160 collisions (for security). For instance, it shouldn't be feasible
161 to come up with a derivation whose output path collides with the
162 path for a copied source. The former would have a <s> starting with
163 "output:out:", while the latter would have a <2> starting with
168 Path
makeStorePath(const string
& type
,
169 const Hash
& hash
, const string
& name
)
171 /* e.g., "source:sha256:1abc...:/nix/store:foo.tar.gz" */
172 string s
= type
+ ":sha256:" + printHash(hash
) + ":"
173 + settings
.nixStore
+ ":" + name
;
175 checkStoreName(name
);
177 return settings
.nixStore
+ "/"
178 + printHash32(compressHash(hashString(htSHA256
, s
), 20))
183 Path
makeOutputPath(const string
& id
,
184 const Hash
& hash
, const string
& name
)
186 return makeStorePath("output:" + id
, hash
,
187 name
+ (id
== "out" ? "" : "-" + id
));
191 Path
makeFixedOutputPath(bool recursive
,
192 HashType hashAlgo
, Hash hash
, string name
)
194 return hashAlgo
== htSHA256
&& recursive
195 ? makeStorePath("source", hash
, name
)
196 : makeStorePath("output:out", hashString(htSHA256
,
197 "fixed:out:" + (recursive
? (string
) "r:" : "") +
198 printHashType(hashAlgo
) + ":" + printHash(hash
) + ":"),
203 std::pair
<Path
, Hash
> computeStorePathForPath(const Path
& srcPath
,
204 bool recursive
, HashType hashAlgo
, PathFilter
& filter
)
206 HashType
ht(hashAlgo
);
207 Hash h
= recursive
? hashPath(ht
, srcPath
, filter
).first
: hashFile(ht
, srcPath
);
208 string name
= baseNameOf(srcPath
);
209 Path dstPath
= makeFixedOutputPath(recursive
, hashAlgo
, h
, name
);
210 return std::pair
<Path
, Hash
>(dstPath
, h
);
214 Path
computeStorePathForText(const string
& name
, const string
& s
,
215 const PathSet
& references
)
217 Hash hash
= hashString(htSHA256
, s
);
218 /* Stuff the references (if any) into the type. This is a bit
219 hacky, but we can't put them in `s' since that would be
221 string type
= "text";
222 foreach (PathSet::const_iterator
, i
, references
) {
226 return makeStorePath(type
, hash
, name
);
230 /* Return a string accepted by decodeValidPathInfo() that
231 registers the specified paths as valid. Note: it's the
232 responsibility of the caller to provide a closure. */
233 string
StoreAPI::makeValidityRegistration(const PathSet
& paths
,
234 bool showDerivers
, bool showHash
)
238 foreach (PathSet::iterator
, i
, paths
) {
241 ValidPathInfo info
= queryPathInfo(*i
);
244 s
+= printHash(info
.hash
) + "\n";
245 s
+= (format("%1%\n") % info
.narSize
).str();
248 Path deriver
= showDerivers
? info
.deriver
: "";
251 s
+= (format("%1%\n") % info
.references
.size()).str();
253 foreach (PathSet::iterator
, j
, info
.references
)
261 ValidPathInfo
decodeValidPathInfo(std::istream
& str
, bool hashGiven
)
264 getline(str
, info
.path
);
265 if (str
.eof()) { info
.path
= ""; return info
; }
269 info
.hash
= parseHash(htSHA256
, s
);
271 if (!string2Int(s
, info
.narSize
)) throw Error("number expected");
273 getline(str
, info
.deriver
);
276 if (!string2Int(s
, n
)) throw Error("number expected");
279 info
.references
.insert(s
);
281 if (!str
|| str
.eof()) throw Error("missing input");
286 string
showPaths(const PathSet
& paths
)
289 foreach (PathSet::const_iterator
, i
, paths
) {
290 if (s
.size() != 0) s
+= ", ";
297 void exportPaths(StoreAPI
& store
, const Paths
& paths
,
298 bool sign
, Sink
& sink
)
300 foreach (Paths::const_iterator
, i
, paths
) {
302 store
.exportPath(*i
, sign
, sink
);
307 Path
readStorePath(Source
& from
)
309 Path path
= readString(from
);
310 assertStorePath(path
);
315 template<class T
> T
readStorePaths(Source
& from
)
317 T paths
= readStrings
<T
>(from
);
318 foreach (typename
T::iterator
, i
, paths
) assertStorePath(*i
);
322 template PathSet
readStorePaths(Source
& from
);
327 #include "local-store.hh"
328 #include "serialise.hh"
334 std::shared_ptr
<StoreAPI
> store
;
337 std::shared_ptr
<StoreAPI
> openStore(bool reserveSpace
)
339 return std::shared_ptr
<StoreAPI
>(new LocalStore(reserveSpace
));