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 store") % path
);
39 Path
toStorePath(const Path
& path
)
42 throw Error(format("path `%1%' is not in the 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 string
storePathToName(const Path
& path
)
53 assertStorePath(path
);
54 return string(path
, settings
.nixStore
.size() + 34);
58 void checkStoreName(const string
& name
)
60 string validChars
= "+-._?=";
61 /* Disallow names starting with a dot for possible security
62 reasons (e.g., "." and ".."). */
63 if (string(name
, 0, 1) == ".")
64 throw Error(format("invalid name: `%1%'") % name
);
65 foreach (string::const_iterator
, i
, name
)
66 if (!((*i
>= 'A' && *i
<= 'Z') ||
67 (*i
>= 'a' && *i
<= 'z') ||
68 (*i
>= '0' && *i
<= '9') ||
69 validChars
.find(*i
) != string::npos
))
71 throw Error(format("invalid character `%1%' in name `%2%'")
77 /* Store paths have the following form:
83 <store> = the location of the store, usually /gnu/store
85 <name> = a human readable name for the path, typically obtained
86 from the name attribute of the derivation, or the name of the
87 source file from which the store path is created. For derivation
88 outputs other than the default "out" output, the string "-<id>"
89 is suffixed to <name>.
91 <h> = base-32 representation of the first 160 bits of a SHA-256
92 hash of <s>; the hash part of the store name
94 <s> = the string "<type>:sha256:<h2>:<store>:<name>";
95 note that it includes the location of the store as well as the
96 name to make sure that changes to either of those are reflected
97 in the hash (e.g. you won't get /nix/store/<h>-name1 and
98 /nix/store/<h>-name2 with equal hash parts).
101 "text:<r1>:<r2>:...<rN>"
102 for plain text files written to the store using
103 addTextToStore(); <r1> ... <rN> are the references of the
106 for paths copied to the store using addToStore() when recursive
107 = true and hashAlgo = "sha256"
109 for either the outputs created by derivations, OR paths copied
110 to the store using addToStore() with recursive != true or
111 hashAlgo != "sha256" (in that case "source" is used; it's
112 silly, but it's done that way for compatibility). <id> is the
113 name of the output (usually, "out").
115 <h2> = base-16 representation of a SHA-256 hash of:
116 if <type> = "text:...":
117 the string written to the resulting store path
118 if <type> = "source":
119 the serialisation of the path from which this store path is
120 copied, as returned by hashPath()
121 if <type> = "output:out":
122 for non-fixed derivation outputs:
123 the derivation (see hashDerivationModulo() in
125 for paths copied by addToStore() or produced by fixed-output
127 the string "fixed:out:<rec><algo>:<hash>:", where
128 <rec> = "r:" for recursive (path) hashes, or "" or flat
130 <algo> = "md5", "sha1" or "sha256"
131 <hash> = base-16 representation of the path or flat hash of
132 the contents of the path (or expected contents of the
133 path for fixed-output derivations)
135 It would have been nicer to handle fixed-output derivations under
136 "source", e.g. have something like "source:<rec><algo>", but we're
137 stuck with this for now...
139 The main reason for this way of computing names is to prevent name
140 collisions (for security). For instance, it shouldn't be feasible
141 to come up with a derivation whose output path collides with the
142 path for a copied source. The former would have a <s> starting with
143 "output:out:", while the latter would have a <2> starting with
148 Path
makeStorePath(const string
& type
,
149 const Hash
& hash
, const string
& name
)
151 /* e.g., "source:sha256:1abc...:/nix/store:foo.tar.gz" */
152 string s
= type
+ ":sha256:" + printHash(hash
) + ":"
153 + settings
.nixStore
+ ":" + name
;
155 checkStoreName(name
);
157 return settings
.nixStore
+ "/"
158 + printHash32(compressHash(hashString(htSHA256
, s
), 20))
163 Path
makeOutputPath(const string
& id
,
164 const Hash
& hash
, const string
& name
)
166 return makeStorePath("output:" + id
, hash
,
167 name
+ (id
== "out" ? "" : "-" + id
));
171 Path
makeFixedOutputPath(bool recursive
,
172 HashType hashAlgo
, Hash hash
, string name
)
174 return hashAlgo
== htSHA256
&& recursive
175 ? makeStorePath("source", hash
, name
)
176 : makeStorePath("output:out", hashString(htSHA256
,
177 "fixed:out:" + (recursive
? (string
) "r:" : "") +
178 printHashType(hashAlgo
) + ":" + printHash(hash
) + ":"),
183 Path
computeStorePathForText(const string
& name
, const string
& s
,
184 const PathSet
& references
)
186 Hash hash
= hashString(htSHA256
, s
);
187 /* Stuff the references (if any) into the type. This is a bit
188 hacky, but we can't put them in `s' since that would be
190 string type
= "text";
191 foreach (PathSet::const_iterator
, i
, references
) {
195 return makeStorePath(type
, hash
, name
);
199 /* Return a string accepted by decodeValidPathInfo() that
200 registers the specified paths as valid. Note: it's the
201 responsibility of the caller to provide a closure. */
202 string
StoreAPI::makeValidityRegistration(const PathSet
& paths
,
203 bool showDerivers
, bool showHash
)
207 foreach (PathSet::iterator
, i
, paths
) {
210 ValidPathInfo info
= queryPathInfo(*i
);
213 s
+= printHash(info
.hash
) + "\n";
214 s
+= (format("%1%\n") % info
.narSize
).str();
217 Path deriver
= showDerivers
? info
.deriver
: "";
220 s
+= (format("%1%\n") % info
.references
.size()).str();
222 foreach (PathSet::iterator
, j
, info
.references
)
229 string
showPaths(const PathSet
& paths
)
232 foreach (PathSet::const_iterator
, i
, paths
) {
233 if (s
.size() != 0) s
+= ", ";
240 void exportPaths(StoreAPI
& store
, const Paths
& paths
,
241 bool sign
, Sink
& sink
)
243 foreach (Paths::const_iterator
, i
, paths
) {
245 store
.exportPath(*i
, sign
, sink
);
250 Path
readStorePath(Source
& from
)
252 Path path
= readString(from
);
253 assertStorePath(path
);
258 template<class T
> T
readStorePaths(Source
& from
)
260 T paths
= readStrings
<T
>(from
);
261 foreach (typename
T::iterator
, i
, paths
) assertStorePath(*i
);
265 template PathSet
readStorePaths(Source
& from
);
270 #include "local-store.hh"
271 #include "serialise.hh"
277 std::shared_ptr
<StoreAPI
> store
;
280 std::shared_ptr
<StoreAPI
> openStore(bool reserveSpace
)
282 return std::shared_ptr
<StoreAPI
>(new LocalStore(reserveSpace
));