File: | d/tclmisc.c |
Warning: | line 914, column 12 Dereference of null pointer (loaded from variable 'death') |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* | |||
2 | * The contents of this file are subject to the Mozilla Public License | |||
3 | * Version 1.1 (the "License"); you may not use this file except in | |||
4 | * compliance with the License. You may obtain a copy of the License at | |||
5 | * http://mozilla.org/. | |||
6 | * | |||
7 | * Software distributed under the License is distributed on an "AS IS" | |||
8 | * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See | |||
9 | * the License for the specific language governing rights and limitations | |||
10 | * under the License. | |||
11 | * | |||
12 | * The Original Code is AOLserver Code and related documentation | |||
13 | * distributed by AOL. | |||
14 | * | |||
15 | * The Initial Developer of the Original Code is America Online, | |||
16 | * Inc. Portions created by AOL are Copyright (C) 1999 America Online, | |||
17 | * Inc. All Rights Reserved. | |||
18 | * | |||
19 | * Alternatively, the contents of this file may be used under the terms | |||
20 | * of the GNU General Public License (the "GPL"), in which case the | |||
21 | * provisions of GPL are applicable instead of those above. If you wish | |||
22 | * to allow use of your version of this file only under the terms of the | |||
23 | * GPL and not to allow others to use your version of this file under the | |||
24 | * License, indicate your decision by deleting the provisions above and | |||
25 | * replace them with the notice and other provisions required by the GPL. | |||
26 | * If you do not delete the provisions above, a recipient may use your | |||
27 | * version of this file under either the License or the GPL. | |||
28 | */ | |||
29 | ||||
30 | ||||
31 | /* | |||
32 | * tclmisc.c -- | |||
33 | * | |||
34 | * Implements a lot of Tcl API commands. | |||
35 | */ | |||
36 | ||||
37 | #include "nsd.h" | |||
38 | ||||
39 | /* | |||
40 | * Local functions defined in this file | |||
41 | */ | |||
42 | ||||
43 | static void SHAByteSwap(uint32_t *dest, const uint8_t *src, unsigned int words) | |||
44 | NS_GNUC_NONNULL(1)__attribute__((__nonnull__(1))) NS_GNUC_NONNULL(2)__attribute__((__nonnull__(2))); | |||
45 | static void SHATransform(Ns_CtxSHA1 *sha) | |||
46 | NS_GNUC_NONNULL(1)__attribute__((__nonnull__(1))); | |||
47 | static void MD5Transform(uint32_t buf[4], const uint32_t block[16]) | |||
48 | NS_GNUC_NONNULL(1)__attribute__((__nonnull__(1))) NS_GNUC_NONNULL(2)__attribute__((__nonnull__(2))); | |||
49 | ||||
50 | static int Base64EncodeObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const* objv, int encoding); | |||
51 | static int Base64DecodeObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const* objv, int encoding); | |||
52 | ||||
53 | ||||
54 | /* | |||
55 | *---------------------------------------------------------------------- | |||
56 | * | |||
57 | * Ns_TclPrintfResult -- | |||
58 | * | |||
59 | * Leave a formatted message in the given Tcl interps result. | |||
60 | * | |||
61 | * Results: | |||
62 | * None. | |||
63 | * | |||
64 | * Side effects: | |||
65 | * None. | |||
66 | * | |||
67 | *---------------------------------------------------------------------- | |||
68 | */ | |||
69 | ||||
70 | void | |||
71 | Ns_TclPrintfResult(Tcl_Interp *interp, const char *fmt, ...) | |||
72 | { | |||
73 | va_list ap; | |||
74 | Tcl_DString ds; | |||
75 | ||||
76 | NS_NONNULL_ASSERT(interp != NULL)((void) (0)); | |||
77 | NS_NONNULL_ASSERT(fmt != NULL)((void) (0)); | |||
78 | ||||
79 | Tcl_DStringInit(&ds); | |||
80 | va_start(ap, fmt)__builtin_va_start(ap, fmt); | |||
81 | Ns_DStringVPrintf(&ds, fmt, ap); | |||
82 | va_end(ap)__builtin_va_end(ap); | |||
83 | Tcl_DStringResult(interp, &ds); | |||
84 | } | |||
85 | ||||
86 | ||||
87 | /* | |||
88 | *---------------------------------------------------------------------- | |||
89 | * | |||
90 | * NsTclRunOnceObjCmd -- | |||
91 | * | |||
92 | * Implements "ns_runonce". Run the given script only once. | |||
93 | * | |||
94 | * Results: | |||
95 | * Tcl result. | |||
96 | * | |||
97 | * Side effects: | |||
98 | * Depends on script. | |||
99 | * | |||
100 | *---------------------------------------------------------------------- | |||
101 | */ | |||
102 | ||||
103 | int | |||
104 | NsTclRunOnceObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const* objv) | |||
105 | { | |||
106 | char *script = NULL((void*)0); | |||
107 | int global = (int)NS_FALSE0, result = TCL_OK0; | |||
108 | Ns_ObjvSpec opts[] = { | |||
109 | {"-global", Ns_ObjvBool, &global, INT2PTR(NS_TRUE)((void *)(intptr_t)(1))}, | |||
110 | {"--", Ns_ObjvBreak, NULL((void*)0), NULL((void*)0)}, | |||
111 | {NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0)} | |||
112 | }; | |||
113 | Ns_ObjvSpec args[] = { | |||
114 | {"script", Ns_ObjvString, &script, NULL((void*)0)}, | |||
115 | {NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0)} | |||
116 | }; | |||
117 | ||||
118 | if (Ns_ParseObjv(opts, args, interp, 1, objc, objv) != NS_OK) { | |||
119 | result = TCL_ERROR1; | |||
120 | ||||
121 | } else { | |||
122 | const NsInterp *itPtr = clientData; | |||
123 | int isNew; | |||
124 | static Tcl_HashTable runTable; | |||
125 | static bool_Bool initialized = NS_FALSE0; | |||
126 | ||||
127 | Ns_MasterLock(); | |||
128 | if (!initialized) { | |||
129 | Tcl_InitHashTable(&runTable, TCL_STRING_KEYS(0)); | |||
130 | initialized = NS_TRUE1; | |||
131 | } | |||
132 | (void) Tcl_CreateHashEntry((global != (int)NS_FALSE) ? &runTable :(*(((global != (int)0) ? &runTable : &itPtr->servPtr ->tcl.runTable)->createProc))((global != (int)0) ? & runTable : &itPtr->servPtr->tcl.runTable, (const char *)(script), &isNew) | |||
133 | &itPtr->servPtr->tcl.runTable, script, &isNew)(*(((global != (int)0) ? &runTable : &itPtr->servPtr ->tcl.runTable)->createProc))((global != (int)0) ? & runTable : &itPtr->servPtr->tcl.runTable, (const char *)(script), &isNew); | |||
134 | Ns_MasterUnlock(); | |||
135 | ||||
136 | if (isNew != 0) { | |||
137 | result = Tcl_Eval(interp, script); | |||
138 | } | |||
139 | } | |||
140 | ||||
141 | return result; | |||
142 | } | |||
143 | ||||
144 | ||||
145 | /* | |||
146 | *---------------------------------------------------------------------- | |||
147 | * | |||
148 | * Ns_TclLogErrorInfo -- | |||
149 | * | |||
150 | * Log the global errorInfo variable to the server log along with | |||
151 | * some connection info, if available. | |||
152 | * | |||
153 | * Results: | |||
154 | * Returns a read-only pointer to the complete errorInfo. | |||
155 | * | |||
156 | * Side effects: | |||
157 | * None. | |||
158 | * | |||
159 | *---------------------------------------------------------------------- | |||
160 | */ | |||
161 | ||||
162 | const char * | |||
163 | Ns_TclLogErrorInfo(Tcl_Interp *interp, const char *extraInfo) | |||
164 | { | |||
165 | const NsInterp *itPtr = NsGetInterpData(interp); | |||
166 | const char *errorInfo, *const*logHeaders; | |||
167 | Tcl_DString ds; | |||
168 | ||||
169 | if (extraInfo != NULL((void*)0)) { | |||
170 | Tcl_AddObjErrorInfo(interp, extraInfo, -1); | |||
171 | } | |||
172 | errorInfo = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY)Tcl_GetVar2(interp, "errorInfo", ((void*)0), 1); | |||
173 | if (errorInfo == NULL((void*)0)) { | |||
174 | errorInfo = NS_EMPTY_STRING; | |||
175 | } | |||
176 | if (itPtr != NULL((void*)0) && itPtr->conn != NULL((void*)0)) { | |||
177 | const Ns_Conn *conn = itPtr->conn; | |||
178 | ||||
179 | Ns_DStringInitTcl_DStringInit(&ds); | |||
180 | if (conn->request.method != NULL((void*)0)) { | |||
181 | Ns_DStringVarAppend(&ds, conn->request.method, " ", (char *)0L); | |||
182 | } | |||
183 | if (conn->request.url != NULL((void*)0)) { | |||
184 | Ns_DStringVarAppend(&ds, conn->request.url, ", ", (char *)0L); | |||
185 | } | |||
186 | Ns_DStringVarAppend(&ds, "PeerAddress: ", Ns_ConnPeerAddr(conn), (char *)0L); | |||
187 | ||||
188 | logHeaders = itPtr->servPtr->tcl.errorLogHeaders; | |||
189 | if (logHeaders != NULL((void*)0)) { | |||
190 | const char *const *hdr; | |||
191 | ||||
192 | for (hdr = logHeaders; *hdr != NULL((void*)0); hdr++) { | |||
193 | const char *value = Ns_SetIGet(conn->headers, *hdr); | |||
194 | ||||
195 | if (value != NULL((void*)0)) { | |||
196 | Ns_DStringVarAppend(&ds, ", ", *hdr, ": ", value, (char *)0L); | |||
197 | } | |||
198 | } | |||
199 | } | |||
200 | Ns_Log(Error, "%s\n%s", Ns_DStringValue(&ds)((&ds)->string), errorInfo); | |||
201 | Ns_DStringFreeTcl_DStringFree(&ds); | |||
202 | } else { | |||
203 | Ns_Log(Error, "%s\n%s line %d", Tcl_GetStringResult(interp), errorInfo, | |||
204 | Tcl_GetErrorLine(interp)); | |||
205 | } | |||
206 | ||||
207 | return errorInfo; | |||
208 | } | |||
209 | ||||
210 | ||||
211 | /* | |||
212 | *---------------------------------------------------------------------- | |||
213 | * | |||
214 | * Ns_TclLogError -- | |||
215 | * | |||
216 | * Log the global errorInfo variable to the server log. | |||
217 | * | |||
218 | * Results: | |||
219 | * Returns a read-only pointer to the errorInfo. | |||
220 | * | |||
221 | * Side effects: | |||
222 | * None. | |||
223 | * | |||
224 | *---------------------------------------------------------------------- | |||
225 | */ | |||
226 | ||||
227 | const char * | |||
228 | Ns_TclLogError(Tcl_Interp *interp) | |||
229 | { | |||
230 | return Ns_TclLogErrorInfo(interp, NULL((void*)0)); | |||
231 | } | |||
232 | ||||
233 | ||||
234 | /* | |||
235 | *---------------------------------------------------------------------- | |||
236 | * | |||
237 | * Ns_TclLogErrorRequest -- | |||
238 | * | |||
239 | * Deprecated. See: Ns_TclLoggErrorInfo. | |||
240 | * | |||
241 | * Results: | |||
242 | * Returns a pointer to the read-only errorInfo. | |||
243 | * | |||
244 | * Side effects: | |||
245 | * None. | |||
246 | * | |||
247 | *---------------------------------------------------------------------- | |||
248 | */ | |||
249 | ||||
250 | const char * | |||
251 | Ns_TclLogErrorRequest(Tcl_Interp *interp, Ns_Conn *UNUSED(conn)UNUSED_conn __attribute__((__unused__))) | |||
252 | { | |||
253 | return Ns_TclLogErrorInfo(interp, NULL((void*)0)); | |||
254 | } | |||
255 | ||||
256 | ||||
257 | /* | |||
258 | *---------------------------------------------------------------------- | |||
259 | * | |||
260 | * Ns_LogDeprecated -- | |||
261 | * | |||
262 | * Report that a C-implemented Tcl command is deprecated. | |||
263 | * | |||
264 | * Results: | |||
265 | * None. | |||
266 | * | |||
267 | * Side effects: | |||
268 | * Write log message. | |||
269 | * | |||
270 | *---------------------------------------------------------------------- | |||
271 | */ | |||
272 | ||||
273 | void | |||
274 | Ns_LogDeprecated(Tcl_Obj *const* objv, int objc, const char *alternative, const char *explanation) | |||
275 | { | |||
276 | Tcl_DString ds; | |||
277 | int i; | |||
278 | ||||
279 | Tcl_DStringInit(&ds); | |||
280 | Tcl_DStringAppend(&ds, "'", 1); | |||
281 | for (i = 0; i < objc; i++) { | |||
282 | const char *s; | |||
283 | int len; | |||
284 | ||||
285 | s = Tcl_GetStringFromObj(objv[i], &len); | |||
286 | Tcl_DStringAppend(&ds, s, len); | |||
287 | Tcl_DStringAppend(&ds, " ", 1); | |||
288 | } | |||
289 | Tcl_DStringAppend(&ds, "' is deprecated. ", -1); | |||
290 | if (alternative != NULL((void*)0)) { | |||
291 | Tcl_DStringAppend(&ds, "Use '", -1); | |||
292 | Tcl_DStringAppend(&ds, alternative, -1); | |||
293 | Tcl_DStringAppend(&ds, "' instead. ", -1); | |||
294 | } | |||
295 | if (explanation != NULL((void*)0)) { | |||
296 | Tcl_DStringAppend(&ds, explanation, -1); | |||
297 | } | |||
298 | Ns_Log(Notice, "%s", Tcl_DStringValue(&ds)((&ds)->string)); | |||
299 | Tcl_DStringFree(&ds); | |||
300 | } | |||
301 | ||||
302 | ||||
303 | /* | |||
304 | *---------------------------------------------------------------------- | |||
305 | * | |||
306 | * Ns_SetNamedVar -- | |||
307 | * | |||
308 | * Set a variable by denoted by a name. Convenience routine for | |||
309 | * tcl-commands, when var names are passed in (e.g. ns_http). | |||
310 | * | |||
311 | * Results: | |||
312 | * NS_TRUE on success, NS_FALSE otherwise. | |||
313 | * | |||
314 | * Side effects: | |||
315 | * None. | |||
316 | * | |||
317 | *---------------------------------------------------------------------- | |||
318 | */ | |||
319 | ||||
320 | bool_Bool | |||
321 | Ns_SetNamedVar(Tcl_Interp *interp, Tcl_Obj *varPtr, Tcl_Obj *valPtr) | |||
322 | { | |||
323 | const Tcl_Obj *errPtr; | |||
324 | ||||
325 | Tcl_IncrRefCount(valPtr)++(valPtr)->refCount; | |||
326 | errPtr = Tcl_ObjSetVar2(interp, varPtr, NULL((void*)0), valPtr, TCL_LEAVE_ERR_MSG0x200); | |||
327 | Tcl_DecrRefCount(valPtr)do { Tcl_Obj *_objPtr = (valPtr); if (_objPtr->refCount-- <= 1) { TclFreeObj(_objPtr); } } while(0); | |||
328 | ||||
329 | return (errPtr != NULL((void*)0)); | |||
330 | } | |||
331 | ||||
332 | ||||
333 | /* | |||
334 | *---------------------------------------------------------------------- | |||
335 | * | |||
336 | * NsTclReflowTextObjCmd -- | |||
337 | * | |||
338 | * Reflow a text to the specified length. | |||
339 | * Implements "ns_reflow_text". | |||
340 | * | |||
341 | * Results: | |||
342 | * Tcl result. | |||
343 | * | |||
344 | * Side effects: | |||
345 | * None. | |||
346 | * | |||
347 | *---------------------------------------------------------------------- | |||
348 | */ | |||
349 | ||||
350 | static void | |||
351 | InsertFreshNewline(Tcl_DString *dsPtr, const char *prefixString, size_t prefixLength, size_t *outputPosPtr) | |||
352 | { | |||
353 | if (prefixLength == 0) { | |||
354 | dsPtr->string[*outputPosPtr] = '\n'; | |||
355 | (*outputPosPtr)++; | |||
356 | } else { | |||
357 | Tcl_DStringSetLength(dsPtr, dsPtr->length + (int)prefixLength); | |||
358 | dsPtr->string[*outputPosPtr] = '\n'; | |||
359 | (*outputPosPtr)++; | |||
360 | memcpy(&dsPtr->string[*outputPosPtr], prefixString, prefixLength); | |||
361 | (*outputPosPtr) += prefixLength; | |||
362 | } | |||
363 | } | |||
364 | ||||
365 | ||||
366 | int | |||
367 | NsTclReflowTextObjCmd(ClientData UNUSED(clientData)UNUSED_clientData __attribute__((__unused__)), Tcl_Interp *interp, int objc, Tcl_Obj *const* objv) | |||
368 | { | |||
369 | int result = TCL_OK0, lineWidth = 80, offset = 0; | |||
370 | char *textString = (char *)NS_EMPTY_STRING, *prefixString = NULL((void*)0); | |||
371 | Ns_ObjvValueRange widthRange = {5, INT_MAX2147483647}; | |||
372 | Ns_ObjvValueRange offsetRange = {0, INT_MAX2147483647}; | |||
373 | Ns_ObjvSpec opts[] = { | |||
374 | {"-width", Ns_ObjvInt, &lineWidth, &widthRange}, | |||
375 | {"-offset", Ns_ObjvInt, &offset, &offsetRange}, | |||
376 | {"-prefix", Ns_ObjvString, &prefixString, NULL((void*)0)}, | |||
377 | {"--", Ns_ObjvBreak, NULL((void*)0), NULL((void*)0)}, | |||
378 | {NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0)} | |||
379 | }; | |||
380 | ||||
381 | Ns_ObjvSpec args[] = { | |||
382 | {"text", Ns_ObjvString, &textString, NULL((void*)0)}, | |||
383 | {NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0)} | |||
384 | }; | |||
385 | ||||
386 | if (Ns_ParseObjv(opts, args, interp, 1, objc, objv) != NS_OK) { | |||
387 | result = TCL_ERROR1; | |||
388 | ||||
389 | } else { | |||
390 | Tcl_DString ds, *dsPtr = &ds; | |||
391 | size_t k, inputPos, outputPos, textLength, prefixLength, currentWidth, nrPrefixes, nrNewLines = 1u; | |||
392 | bool_Bool done = NS_FALSE0; | |||
393 | const char *p; | |||
394 | ||||
395 | textLength = strlen(textString); | |||
396 | prefixLength = (prefixString == NULL((void*)0) ? 0u : strlen(prefixString)); | |||
397 | Tcl_DStringInit(dsPtr); | |||
398 | ||||
399 | p = textString; | |||
400 | while( (p = strchr(p, INTCHAR('\n')((int)((unsigned char)(('\n')))))) != NULL((void*)0)) { | |||
401 | nrNewLines++; | |||
402 | p++; | |||
403 | } | |||
404 | ||||
405 | inputPos = 0u; | |||
406 | if (offset == 0 && prefixLength > 0u) { | |||
407 | /* | |||
408 | * When we have an offset (in an incremental operation) adding a | |||
409 | * prefix automatically makes little sense. When needed, the | |||
410 | * prefix could be easily done on the client side. | |||
411 | */ | |||
412 | memcpy(dsPtr->string, prefixString, prefixLength); | |||
413 | outputPos = prefixLength; | |||
414 | nrPrefixes = nrNewLines; | |||
415 | } else { | |||
416 | outputPos = 0u; | |||
417 | nrPrefixes = ((nrNewLines > 0u) ? (nrNewLines - 1) : 0u); | |||
418 | } | |||
419 | ||||
420 | /* | |||
421 | * Set the length of the Tcl_DString to the same size as the input | |||
422 | * string plus for every linebreak+1 the prefixString. | |||
423 | */ | |||
424 | Tcl_DStringSetLength(dsPtr, (int)(textLength + nrPrefixes * prefixLength)); | |||
425 | ||||
426 | while (inputPos < textLength && !done) { | |||
427 | size_t processedPos; | |||
428 | ||||
429 | /* | |||
430 | * Copy the input string until lineWidth is reached | |||
431 | */ | |||
432 | processedPos = inputPos; | |||
433 | for (currentWidth = (size_t)offset; (int)currentWidth < lineWidth; currentWidth++) { | |||
434 | ||||
435 | if ( inputPos < textLength) { | |||
436 | dsPtr->string[outputPos] = textString[inputPos]; | |||
437 | ||||
438 | /* | |||
439 | * In case there are newlines in the text, insert it with | |||
440 | * the prefix and reset the currentWidth. The size for of | |||
441 | * the prefix is already included in the allocated space of | |||
442 | * the string. | |||
443 | */ | |||
444 | outputPos++; | |||
445 | if ( textString[inputPos] == '\n') { | |||
446 | if (prefixLength > 0u) { | |||
447 | memcpy(&dsPtr->string[outputPos], prefixString, prefixLength); | |||
448 | outputPos += prefixLength; | |||
449 | } | |||
450 | currentWidth = 0u; | |||
451 | processedPos = inputPos; | |||
452 | } | |||
453 | inputPos++; | |||
454 | } else { | |||
455 | /* | |||
456 | * We reached the end of the inputString and we are done. | |||
457 | */ | |||
458 | done = NS_TRUE1; | |||
459 | break; | |||
460 | } | |||
461 | } | |||
462 | offset = 0; | |||
463 | ||||
464 | if (!done) { | |||
465 | bool_Bool whitesspaceFound = NS_FALSE0; | |||
466 | size_t origOutputPos = outputPos; | |||
467 | /* | |||
468 | * Search for the last whitespace in the input from the end | |||
469 | */ | |||
470 | for ( k = inputPos; k > processedPos; k--, outputPos--) { | |||
471 | if ( CHARTYPE(space, textString[k])(((*__ctype_b_loc ())[(int) (((int)((unsigned char)(textString [k]))))] & (unsigned short int) _ISspace)) != 0) { | |||
472 | whitesspaceFound = NS_TRUE1; | |||
473 | /* | |||
474 | * Replace the whitespace by a "\n" followed by the | |||
475 | * prefix string; we have to make sure that the dsPtr | |||
476 | * can held the additional prefix as well. | |||
477 | */ | |||
478 | InsertFreshNewline(dsPtr, prefixString, prefixLength, &outputPos); | |||
479 | /* | |||
480 | * Reset the inputPositon | |||
481 | */ | |||
482 | inputPos = k + 1u; | |||
483 | break; | |||
484 | } | |||
485 | } | |||
486 | if (!whitesspaceFound) { | |||
487 | /* | |||
488 | * The last chunk did not include a whitespace. This | |||
489 | * happens when we find overflowing elements. In this | |||
490 | * case, let the line overflow (read forward until we | |||
491 | * find a space, and continue as usual. | |||
492 | */ | |||
493 | outputPos = origOutputPos; | |||
494 | for (k = inputPos; k < textLength; k++) { | |||
495 | if ( CHARTYPE(space, textString[k])(((*__ctype_b_loc ())[(int) (((int)((unsigned char)(textString [k]))))] & (unsigned short int) _ISspace)) != 0) { | |||
496 | InsertFreshNewline(dsPtr, prefixString, prefixLength, &outputPos); | |||
497 | inputPos++; | |||
498 | break; | |||
499 | } else { | |||
500 | dsPtr->string[outputPos] = textString[inputPos]; | |||
501 | outputPos++; | |||
502 | inputPos++; | |||
503 | } | |||
504 | } | |||
505 | } | |||
506 | } | |||
507 | } | |||
508 | Tcl_DStringResult(interp, &ds); | |||
509 | } | |||
510 | return result; | |||
511 | } | |||
512 | ||||
513 | ||||
514 | /* | |||
515 | *---------------------------------------------------------------------- | |||
516 | * | |||
517 | * NsTclTrimObjCmd -- | |||
518 | * | |||
519 | * Multiline trim with optional delimiter and builtin substitution | |||
520 | * (latter is not really needed but convenient). Trim leading spaces on | |||
521 | * multiple lines. | |||
522 | * | |||
523 | * Implements "ns_trim". | |||
524 | * | |||
525 | * Results: | |||
526 | * Tcl result. | |||
527 | * | |||
528 | * Side effects: | |||
529 | * None. | |||
530 | * | |||
531 | *---------------------------------------------------------------------- | |||
532 | */ | |||
533 | ||||
534 | int | |||
535 | NsTclTrimObjCmd(ClientData UNUSED(clientData)UNUSED_clientData __attribute__((__unused__)), Tcl_Interp *interp, int objc, Tcl_Obj *const* objv) | |||
536 | { | |||
537 | int result = TCL_OK0, substInt = 0; | |||
538 | Tcl_Obj *textObj; | |||
539 | char *delimiterString = NULL((void*)0), *prefixString = NULL((void*)0); | |||
540 | Ns_ObjvSpec opts[] = { | |||
541 | {"-subst", Ns_ObjvBool, &substInt, INT2PTR(NS_TRUE)((void *)(intptr_t)(1))}, | |||
542 | {"-delimiter", Ns_ObjvString, &delimiterString, NULL((void*)0)}, | |||
543 | {"-prefix", Ns_ObjvString, &prefixString, NULL((void*)0)}, | |||
544 | {"--", Ns_ObjvBreak, NULL((void*)0), NULL((void*)0)}, | |||
545 | {NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0)} | |||
546 | }; | |||
547 | ||||
548 | Ns_ObjvSpec args[] = { | |||
549 | {"text", Ns_ObjvObj, &textObj, NULL((void*)0)}, | |||
550 | {NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0)} | |||
551 | }; | |||
552 | ||||
553 | if (Ns_ParseObjv(opts, args, interp, 1, objc, objv) != NS_OK) { | |||
554 | result = TCL_ERROR1; | |||
555 | ||||
556 | } else if (delimiterString != NULL((void*)0) && prefixString != NULL((void*)0)) { | |||
557 | Ns_TclPrintfResult(interp, "invalid arguments: either -prefix or -delimiter can be specified"); | |||
558 | result = TCL_ERROR1; | |||
559 | ||||
560 | } else if (delimiterString != NULL((void*)0) && strlen(delimiterString) != 1) { | |||
561 | Ns_TclPrintfResult(interp, "invalid arguments: -delimiter must be a single character"); | |||
562 | result = TCL_ERROR1; | |||
563 | ||||
564 | } else { | |||
565 | Tcl_DString ds, *dsPtr = &ds; | |||
566 | int textLength; | |||
567 | char *p; | |||
568 | const char *endOfString; | |||
569 | ||||
570 | Tcl_DStringInit(dsPtr); | |||
571 | ||||
572 | if (substInt != 0) { | |||
573 | textObj = Tcl_SubstObj(interp, textObj, TCL_SUBST_ALL007); | |||
574 | } | |||
575 | p = Tcl_GetStringFromObj(textObj, &textLength); | |||
576 | endOfString = p + textLength; | |||
577 | ||||
578 | if (prefixString != NULL((void*)0)) { | |||
579 | size_t prefixLength = strlen(prefixString); | |||
580 | ||||
581 | while(likely(p < endOfString)(__builtin_expect((p < endOfString), 1))) { | |||
582 | const char *eolString; | |||
583 | char *j; | |||
584 | ptrdiff_t length; | |||
585 | ||||
586 | if (strncmp(p, prefixString, prefixLength) == 0) { | |||
587 | j = p + prefixLength; | |||
588 | } else { | |||
589 | j = p; | |||
590 | } | |||
591 | eolString = strchr(j, INTCHAR('\n')((int)((unsigned char)(('\n'))))); | |||
592 | if (likely(eolString != NULL)(__builtin_expect((eolString != ((void*)0)), 1))) { | |||
593 | length = (eolString - j) + 1; | |||
594 | } else { | |||
595 | length = (endOfString - j); | |||
596 | } | |||
597 | Tcl_DStringAppend(dsPtr, j, (int)length); | |||
598 | ||||
599 | p = j + length; | |||
600 | } | |||
601 | } else { | |||
602 | /* | |||
603 | * No "-prefix" | |||
604 | */ | |||
605 | while(likely(p < endOfString)(__builtin_expect((p < endOfString), 1))) { | |||
606 | const char *eolString; | |||
607 | char *j; | |||
608 | ptrdiff_t length; | |||
609 | ||||
610 | for (j = p; likely(j < endOfString)(__builtin_expect((j < endOfString), 1)); j++) { | |||
611 | if (CHARTYPE(space, *j)(((*__ctype_b_loc ())[(int) (((int)((unsigned char)(*j))))] & (unsigned short int) _ISspace)) != 0) { | |||
612 | continue; | |||
613 | } | |||
614 | if (delimiterString != NULL((void*)0) && *j == *delimiterString) { | |||
615 | j++; | |||
616 | break; | |||
617 | } | |||
618 | break; | |||
619 | } | |||
620 | eolString = strchr(j, INTCHAR('\n')((int)((unsigned char)(('\n'))))); | |||
621 | if (likely(eolString != NULL)(__builtin_expect((eolString != ((void*)0)), 1))) { | |||
622 | length = (eolString - j) + 1; | |||
623 | } else { | |||
624 | length = (endOfString - j); | |||
625 | } | |||
626 | Tcl_DStringAppend(dsPtr, j, (int)length); | |||
627 | ||||
628 | p = j + length; | |||
629 | } | |||
630 | } | |||
631 | Tcl_DStringResult(interp, dsPtr); | |||
632 | ||||
633 | } | |||
634 | return result; | |||
635 | } | |||
636 | ||||
637 | ||||
638 | ||||
639 | /* | |||
640 | *---------------------------------------------------------------------- | |||
641 | * | |||
642 | * NsTclHrefsObjCmd -- | |||
643 | * | |||
644 | * Implements "ns_hrefs". | |||
645 | * | |||
646 | * Results: | |||
647 | * Tcl result. | |||
648 | * | |||
649 | * Side effects: | |||
650 | * See docs. | |||
651 | * | |||
652 | *---------------------------------------------------------------------- | |||
653 | */ | |||
654 | ||||
655 | int | |||
656 | NsTclHrefsObjCmd(ClientData UNUSED(clientData)UNUSED_clientData __attribute__((__unused__)), Tcl_Interp *interp, int objc, Tcl_Obj *const* objv) | |||
657 | { | |||
658 | int result = TCL_OK0; | |||
659 | char *htmlString = (char *)NS_EMPTY_STRING; | |||
660 | Ns_ObjvSpec args[] = { | |||
661 | {"html", Ns_ObjvString, &htmlString, NULL((void*)0)}, | |||
662 | {NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0)} | |||
663 | }; | |||
664 | ||||
665 | if (Ns_ParseObjv(NULL((void*)0), args, interp, 1, objc, objv) != NS_OK) { | |||
666 | result = TCL_ERROR1; | |||
667 | ||||
668 | } else { | |||
669 | char *s, *e; | |||
670 | const char *p; | |||
671 | Tcl_Obj *listObj = Tcl_NewListObj(0, NULL((void*)0)); | |||
672 | ||||
673 | p = htmlString; | |||
674 | while (((s = strchr(p, INTCHAR('<')((int)((unsigned char)(('<')))))) != NULL((void*)0)) && ((e = strchr(s, INTCHAR('>')((int)((unsigned char)(('>')))))) != NULL((void*)0))) { | |||
675 | ++s; | |||
676 | *e = '\0'; | |||
677 | while (*s != '\0' && CHARTYPE(space, *s)(((*__ctype_b_loc ())[(int) (((int)((unsigned char)(*s))))] & (unsigned short int) _ISspace)) != 0) { | |||
678 | ++s; | |||
679 | } | |||
680 | if ((*s == 'a' || *s == 'A') && CHARTYPE(space, s[1])(((*__ctype_b_loc ())[(int) (((int)((unsigned char)(s[1]))))] & (unsigned short int) _ISspace)) != 0) { | |||
681 | ++s; | |||
682 | while (*s != '\0') { | |||
683 | if (strncasecmp(s, "href", 4u) == 0) { | |||
684 | s += 4; | |||
685 | while (*s != '\0' && CHARTYPE(space, *s)(((*__ctype_b_loc ())[(int) (((int)((unsigned char)(*s))))] & (unsigned short int) _ISspace)) != 0) { | |||
686 | ++s; | |||
687 | } | |||
688 | if (*s == '=') { | |||
689 | char save, *he; | |||
690 | ||||
691 | ++s; | |||
692 | while (*s != '\0' && CHARTYPE(space, *s)(((*__ctype_b_loc ())[(int) (((int)((unsigned char)(*s))))] & (unsigned short int) _ISspace)) != 0) { | |||
693 | ++s; | |||
694 | } | |||
695 | he = NULL((void*)0); | |||
696 | if (*s == '\'' || *s == '"') { | |||
697 | he = strchr(s+1, INTCHAR(*s)((int)((unsigned char)((*s))))); | |||
698 | ++s; | |||
699 | } | |||
700 | if (he == NULL((void*)0)) { | |||
701 | assert(s != NULL)((void) (0)); | |||
702 | he = s; | |||
703 | while (*he != '\0' && CHARTYPE(space, *he)(((*__ctype_b_loc ())[(int) (((int)((unsigned char)(*he))))] & (unsigned short int) _ISspace)) == 0) { | |||
704 | ++he; | |||
705 | } | |||
706 | } | |||
707 | save = *he; | |||
708 | *he = '\0'; | |||
709 | Tcl_ListObjAppendElement(interp, listObj, Tcl_NewStringObj(s, -1)); | |||
710 | *he = save; | |||
711 | break; | |||
712 | } | |||
713 | } | |||
714 | if (*s == '\'' || *s == '\"') { | |||
715 | char quote = *s; | |||
716 | ||||
717 | do { | |||
718 | s++; | |||
719 | } while (*s != '\0' && *s != quote); | |||
720 | continue; | |||
721 | } | |||
722 | if (*s != '\0') { | |||
723 | ++s; | |||
724 | } | |||
725 | } | |||
726 | } | |||
727 | *e++ = '>'; | |||
728 | p = e; | |||
729 | } | |||
730 | Tcl_SetObjResult(interp, listObj); | |||
731 | } | |||
732 | return result; | |||
733 | } | |||
734 | ||||
735 | ||||
736 | /* | |||
737 | *---------------------------------------------------------------------- | |||
738 | * | |||
739 | * Base64EncodeObjCmd -- | |||
740 | * | |||
741 | * Implements "ns_uuencode", "ns_base64encode", and "ns_base64urlencode". | |||
742 | * | |||
743 | * Results: | |||
744 | * Tcl result. | |||
745 | * | |||
746 | * Side effects: | |||
747 | * See docs. | |||
748 | * | |||
749 | *---------------------------------------------------------------------- | |||
750 | */ | |||
751 | ||||
752 | #if 0 | |||
753 | static void hexPrint(const char *msg, const unsigned char *octects, size_t octectLength) | |||
754 | { | |||
755 | size_t i; | |||
756 | fprintf(stderr, "%s octectLength %" PRIuz ":", msg, octectLength)__fprintf_chk (stderr, 2 - 1, "%s octectLength %" "zu" ":", msg , octectLength); | |||
757 | for (i = 0; i < octectLength; i++) { | |||
758 | fprintf(stderr, "%.2x ", octects[i] & 0xff)__fprintf_chk (stderr, 2 - 1, "%.2x ", octects[i] & 0xff); | |||
759 | } | |||
760 | fprintf(stderr, "\n")__fprintf_chk (stderr, 2 - 1, "\n"); | |||
761 | } | |||
762 | #endif | |||
763 | ||||
764 | static int | |||
765 | Base64EncodeObjCmd(ClientData UNUSED(clientData)UNUSED_clientData __attribute__((__unused__)), Tcl_Interp *interp, int objc, Tcl_Obj *const* objv, | |||
766 | int encoding) | |||
767 | { | |||
768 | int result = TCL_OK0, isBinary = 0; | |||
769 | Tcl_Obj *charsObj; | |||
770 | Ns_ObjvSpec opts[] = { | |||
771 | {"-binary", Ns_ObjvBool, &isBinary, INT2PTR(NS_TRUE)((void *)(intptr_t)(1))}, | |||
772 | {"--", Ns_ObjvBreak, NULL((void*)0), NULL((void*)0)}, | |||
773 | {NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0)} | |||
774 | }; | |||
775 | Ns_ObjvSpec args[] = { | |||
776 | {"string", Ns_ObjvObj, &charsObj, NULL((void*)0)}, | |||
777 | {NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0)} | |||
778 | }; | |||
779 | ||||
780 | if (Ns_ParseObjv(opts, args, interp, 1, objc, objv) != NS_OK) { | |||
781 | result = TCL_ERROR1; | |||
782 | ||||
783 | } else { | |||
784 | char *buffer; | |||
785 | size_t size; | |||
786 | int nbytes = 0; | |||
787 | Tcl_DString ds; | |||
788 | const unsigned char *bytes; | |||
789 | ||||
790 | Tcl_DStringInit(&ds); | |||
791 | bytes = Ns_GetBinaryString(charsObj, isBinary == 1, &nbytes, &ds); | |||
792 | //hexPrint("source ", bytes, (size_t)nbytes); | |||
793 | ||||
794 | size = (size_t)nbytes; | |||
795 | buffer = ns_malloc(1u + (4u * MAX(size, 2u)(((size)>(2u))?(size):(2u))) / 2u); | |||
796 | (void)Ns_HtuuEncode2(bytes, size, buffer, encoding); | |||
797 | ||||
798 | Tcl_SetResult(interp, buffer, (Tcl_FreeProc *) ns_free); | |||
799 | Tcl_DStringFree(&ds); | |||
800 | } | |||
801 | return result; | |||
802 | } | |||
803 | ||||
804 | int | |||
805 | NsTclBase64EncodeObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const* objv) | |||
806 | { | |||
807 | return Base64EncodeObjCmd(clientData, interp, objc, objv, 0); | |||
808 | } | |||
809 | int | |||
810 | NsTclBase64UrlEncodeObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const* objv) | |||
811 | { | |||
812 | return Base64EncodeObjCmd(clientData, interp, objc, objv, 1); | |||
813 | } | |||
814 | ||||
815 | ||||
816 | /* | |||
817 | *---------------------------------------------------------------------- | |||
818 | * | |||
819 | * Base64DecodeObjCmd -- | |||
820 | * | |||
821 | * Implements "ns_uudecode", "ns_base64decode", and "ns_base64urldecode". | |||
822 | * | |||
823 | * Results: | |||
824 | * Tcl result. | |||
825 | * | |||
826 | * Side effects: | |||
827 | * See docs. | |||
828 | * | |||
829 | *---------------------------------------------------------------------- | |||
830 | */ | |||
831 | ||||
832 | static int | |||
833 | Base64DecodeObjCmd(ClientData UNUSED(clientData)UNUSED_clientData __attribute__((__unused__)), Tcl_Interp *interp, int objc, Tcl_Obj *const* objv, | |||
834 | int encoding) | |||
835 | { | |||
836 | int result = TCL_OK0, isBinary = 0; | |||
837 | Tcl_Obj *charsObj; | |||
838 | Ns_ObjvSpec opts[] = { | |||
839 | {"-binary", Ns_ObjvBool, &isBinary, INT2PTR(NS_TRUE)((void *)(intptr_t)(1))}, | |||
840 | {"--", Ns_ObjvBreak, NULL((void*)0), NULL((void*)0)}, | |||
841 | {NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0)} | |||
842 | }; | |||
843 | Ns_ObjvSpec args[] = { | |||
844 | {"string", Ns_ObjvObj, &charsObj, NULL((void*)0)}, | |||
845 | {NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0)} | |||
846 | }; | |||
847 | ||||
848 | if (Ns_ParseObjv(opts, args, interp, 1, objc, objv) != NS_OK) { | |||
849 | result = TCL_ERROR1; | |||
850 | ||||
851 | } else { | |||
852 | int len; | |||
853 | size_t size; | |||
854 | unsigned char *decoded; | |||
855 | const char *chars = Tcl_GetStringFromObj(charsObj, &len); | |||
856 | ||||
857 | size = (size_t)len + 3u; | |||
858 | decoded = (unsigned char *)ns_malloc(size); | |||
859 | size = Ns_HtuuDecode2(chars, decoded, size, encoding); | |||
860 | // hexPrint("decoded", decoded, size); | |||
861 | ||||
862 | if (isBinary) { | |||
863 | Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(decoded, (int)size)); | |||
864 | ||||
865 | } else { | |||
866 | Tcl_DString ds, *dsPtr = &ds; | |||
867 | ||||
868 | Tcl_DStringInit(dsPtr); | |||
869 | Tcl_ExternalToUtfDString(NULL((void*)0), (char *)decoded, (int)size, dsPtr); | |||
870 | Tcl_DStringResult(interp, dsPtr); | |||
871 | } | |||
872 | ||||
873 | ns_free(decoded); | |||
874 | } | |||
875 | ||||
876 | return result; | |||
877 | } | |||
878 | int | |||
879 | NsTclBase64DecodeObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const* objv) | |||
880 | { | |||
881 | return Base64DecodeObjCmd(clientData, interp, objc, objv, 0); | |||
882 | } | |||
883 | int | |||
884 | NsTclBase64UrlDecodeObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const* objv) | |||
885 | { | |||
886 | return Base64DecodeObjCmd(clientData, interp, objc, objv, 1); | |||
887 | } | |||
888 | ||||
889 | ||||
890 | ||||
891 | /* | |||
892 | *---------------------------------------------------------------------- | |||
893 | * | |||
894 | * NsTclCrashObjCmd -- | |||
895 | * | |||
896 | * Implements "ns_crash". Crash the server to test exception handling. | |||
897 | * | |||
898 | * Results: | |||
899 | * None. | |||
900 | * | |||
901 | * Side effects: | |||
902 | * Server will segfault. | |||
903 | * | |||
904 | *---------------------------------------------------------------------- | |||
905 | */ | |||
906 | ||||
907 | int | |||
908 | NsTclCrashObjCmd(ClientData UNUSED(clientData)UNUSED_clientData __attribute__((__unused__)), Tcl_Interp *UNUSED(interp)UNUSED_interp __attribute__((__unused__)), | |||
909 | int UNUSED(argc)UNUSED_argc __attribute__((__unused__)), Tcl_Obj *const* UNUSED(objv)UNUSED_objv __attribute__((__unused__))) | |||
910 | { | |||
911 | char *death; | |||
912 | ||||
913 | death = NULL((void*)0); | |||
| ||||
914 | *death = 'x'; | |||
| ||||
915 | ||||
916 | return TCL_ERROR1; | |||
917 | } | |||
918 | ||||
919 | ||||
920 | /* | |||
921 | *---------------------------------------------------------------------- | |||
922 | * | |||
923 | * NsTclCryptObjCmd -- | |||
924 | * | |||
925 | * Implements "ns_crypt". | |||
926 | * | |||
927 | * Results: | |||
928 | * Tcl result. | |||
929 | * | |||
930 | * Side effects: | |||
931 | * See docs. | |||
932 | * | |||
933 | *---------------------------------------------------------------------- | |||
934 | */ | |||
935 | ||||
936 | int | |||
937 | NsTclCryptObjCmd(ClientData UNUSED(clientData)UNUSED_clientData __attribute__((__unused__)), Tcl_Interp *interp, int objc, Tcl_Obj *const* objv) | |||
938 | { | |||
939 | int result = TCL_OK0; | |||
940 | char *keyString, *saltString; | |||
941 | Ns_ObjvSpec args[] = { | |||
942 | {"key", Ns_ObjvString, &keyString, NULL((void*)0)}, | |||
943 | {"salt", Ns_ObjvString, &saltString, NULL((void*)0)}, | |||
944 | {NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0)} | |||
945 | }; | |||
946 | ||||
947 | if (Ns_ParseObjv(NULL((void*)0), args, interp, 1, objc, objv) != NS_OK) { | |||
948 | result = TCL_ERROR1; | |||
949 | ||||
950 | } else { | |||
951 | if (strlen(saltString) != 2 ) { | |||
952 | Ns_TclPrintfResult(interp, "salt string must be 2 characters long"); | |||
953 | result = TCL_ERROR1; | |||
954 | ||||
955 | } else { | |||
956 | char buf[NS_ENCRYPT_BUFSIZE128]; | |||
957 | ||||
958 | Tcl_SetObjResult(interp, | |||
959 | Tcl_NewStringObj(Ns_Encrypt(keyString, saltString, buf), -1)); | |||
960 | } | |||
961 | } | |||
962 | return result; | |||
963 | } | |||
964 | ||||
965 | /* | |||
966 | * The SHA1 routines are borrowed from libmd: | |||
967 | * | |||
968 | * * sha.c - NIST Secure Hash Algorithm, FIPS PUB 180 and 180.1. | |||
969 | * * The algorithm is by spook(s) unknown at the U.S. National Security Agency. | |||
970 | * * | |||
971 | * * Written 2 September 1992, Peter C. Gutmann. | |||
972 | * * This implementation placed in the public domain. | |||
973 | * * | |||
974 | * * Modified 1 June 1993, Colin Plumb. | |||
975 | * * Modified for the new SHS based on Peter Gutmann's work, | |||
976 | * * 18 July 1994, Colin Plumb. | |||
977 | * * | |||
978 | * * Renamed to SHA and comments updated a bit 1 November 1995, Colin Plumb. | |||
979 | * * These modifications placed in the public domain. | |||
980 | * * | |||
981 | * * Comments to pgut1@cs.aukuni.ac.nz | |||
982 | * * | |||
983 | * * Hacked for use in libmd by Martin Hinner <mhi@penguin.cz> | |||
984 | * | |||
985 | * This Tcl library was hacked by Jon Salz <jsalz@mit.edu>. | |||
986 | * | |||
987 | */ | |||
988 | ||||
989 | /* | |||
990 | * Define to 1 for FIPS 180.1 version (with extra rotate in prescheduling), | |||
991 | * 0 for FIPS 180 version (with the mysterious "weakness" that the NSA | |||
992 | * isn't talking about). | |||
993 | */ | |||
994 | ||||
995 | #define SHA_VERSION1 1 | |||
996 | ||||
997 | #define SHA_BLOCKBYTES64u 64u | |||
998 | ||||
999 | /* | |||
1000 | Shuffle the bytes into big-endian order within words, as per the | |||
1001 | SHA spec. | |||
1002 | */ | |||
1003 | ||||
1004 | ||||
1005 | static void | |||
1006 | SHAByteSwap(uint32_t *dest, const uint8_t *src, unsigned int words) | |||
1007 | { | |||
1008 | do { | |||
1009 | *dest++ = (uint32_t) ((unsigned) src[0] << 8 | src[1]) << 16 | | |||
1010 | ((unsigned) src[2] << 8 | src[3]); | |||
1011 | src += 4; | |||
1012 | } while (--words > 0u); | |||
1013 | } | |||
1014 | ||||
1015 | /* | |||
1016 | * Initialize the SHA values | |||
1017 | */ | |||
1018 | void Ns_CtxSHAInit(Ns_CtxSHA1 * ctx) | |||
1019 | { | |||
1020 | ||||
1021 | /* | |||
1022 | * Set the h-vars to their initial values. | |||
1023 | */ | |||
1024 | ctx->iv[0] = 0x67452301u; | |||
1025 | ctx->iv[1] = 0xEFCDAB89u; | |||
1026 | ctx->iv[2] = 0x98BADCFEu; | |||
1027 | ctx->iv[3] = 0x10325476u; | |||
1028 | ctx->iv[4] = 0xC3D2E1F0u; | |||
1029 | ||||
1030 | /* | |||
1031 | * Initialize bit count | |||
1032 | */ | |||
1033 | #if defined(HAVE_64BIT1) | |||
1034 | ctx->bytes = 0u; | |||
1035 | #else | |||
1036 | ctx->bytesHi = 0u; | |||
1037 | ctx->bytesLo = 0u; | |||
1038 | #endif | |||
1039 | } | |||
1040 | ||||
1041 | /* | |||
1042 | * The SHA f()-functions. The f1 and f3 functions can be optimized to | |||
1043 | * save one boolean operation each - thanks to Rich Schroeppel, | |||
1044 | * rcs@cs.arizona.edu for discovering this. | |||
1045 | * The f3 function can be modified to use an addition to combine the | |||
1046 | * two halves rather than OR, allowing more opportunity for using | |||
1047 | * associativity in optimization. (Colin Plumb) | |||
1048 | */ | |||
1049 | #define f1(x, y, z)( (z) ^ ((x) & ((y) ^ (z)) ) ) ( (z) ^ ((x) & ((y) ^ (z)) ) ) /* Rounds 0-19 */ | |||
1050 | #define f2(x, y, z)( (x) ^ (y) ^ (z) ) ( (x) ^ (y) ^ (z) ) /* Rounds 20-39 */ | |||
1051 | #define f3(x, y, z)( ((x) & (y)) + ((z) & ((x) ^ (y)) ) ) ( ((x) & (y)) + ((z) & ((x) ^ (y)) ) ) /* Rounds 40-59 */ | |||
1052 | #define f4(x, y, z)( (x) ^ (y) ^ (z) ) ( (x) ^ (y) ^ (z) ) /* Rounds 60-79 */ | |||
1053 | ||||
1054 | /* | |||
1055 | * The SHA Mysterious Constants. | |||
1056 | */ | |||
1057 | #define K2(0x5A827999u) (0x5A827999u) /* Rounds 0 -19 - floor(sqrt(2) * 2^30) */ | |||
1058 | #define K3(0x6ED9EBA1u) (0x6ED9EBA1u) /* Rounds 20-39 - floor(sqrt(3) * 2^30) */ | |||
1059 | #define K5(0x8F1BBCDCu) (0x8F1BBCDCu) /* Rounds 40-59 - floor(sqrt(5) * 2^30) */ | |||
1060 | #define K10(0xCA62C1D6u) (0xCA62C1D6u) /* Rounds 60-79 - floor(sqrt(10) * 2^30) */ | |||
1061 | ||||
1062 | /* | |||
1063 | * 32-bit rotate left - kludged with shifts | |||
1064 | */ | |||
1065 | #define ROTL(n, X)( ((X) << (n)) | ((X) >> (32-(n))) ) ( ((X) << (n)) | ((X) >> (32-(n))) ) | |||
1066 | ||||
1067 | /* | |||
1068 | * The initial expanding function | |||
1069 | * | |||
1070 | * The hash function is defined over an 80-word expanded input array W, | |||
1071 | * where the first 16 are copies of the input data, and the remaining 64 | |||
1072 | * are defined by W[i] = W[i-16] ^ W[i-14] ^ W[i-8] ^ W[i-3]. This | |||
1073 | * implementation generates these values on the fly in a circular buffer. | |||
1074 | * | |||
1075 | * The new "corrected" FIPS 180.1 added a 1-bit left rotate to this | |||
1076 | * computation of W[i]. | |||
1077 | * | |||
1078 | * The expandx() version doesn't write the result back, which can be | |||
1079 | * used for the last three rounds since those outputs are never used. | |||
1080 | */ | |||
1081 | #if SHA_VERSION1 /* FIPS 180.1 */ | |||
1082 | ||||
1083 | #define expandx(W, i)(t = W[(i)&15u] ^ W[((i)-14)&15u] ^ W[((i)-8)&15u ] ^ W[((i)-3)&15u], ( ((t) << (1)) | ((t) >> ( 32-(1))) )) (t = W[(i)&15u] ^ W[((i)-14)&15u] ^ W[((i)-8)&15u] ^ W[((i)-3)&15u], \ | |||
1084 | ROTL(1, t)( ((t) << (1)) | ((t) >> (32-(1))) )) | |||
1085 | #define expand(W, i)(W[(i)&15u] = (t = W[((i))&15u] ^ W[(((i))-14)&15u ] ^ W[(((i))-8)&15u] ^ W[(((i))-3)&15u], ( ((t) << (1)) | ((t) >> (32-(1))) ))) (W[(i)&15u] = expandx(W, (i))(t = W[((i))&15u] ^ W[(((i))-14)&15u] ^ W[(((i))-8)& 15u] ^ W[(((i))-3)&15u], ( ((t) << (1)) | ((t) >> (32-(1))) ))) | |||
1086 | ||||
1087 | #else /* Old FIPS 180 */ | |||
1088 | ||||
1089 | #define expandx(W, i)(t = W[(i)&15u] ^ W[((i)-14)&15u] ^ W[((i)-8)&15u ] ^ W[((i)-3)&15u], ( ((t) << (1)) | ((t) >> ( 32-(1))) )) (W[(i)&15u] ^ W[((i)-14)&15u] ^ W[((i)-8)&15u] ^ W[((i)-3)&15u]) | |||
1090 | #define expand(W, i)(W[(i)&15u] = (t = W[((i))&15u] ^ W[(((i))-14)&15u ] ^ W[(((i))-8)&15u] ^ W[(((i))-3)&15u], ( ((t) << (1)) | ((t) >> (32-(1))) ))) (W[(i)&15u] ^= W[((i)-14)&15u] ^ W[((i)-8)&15u] ^ W[((i)-3)&15u]) | |||
1091 | ||||
1092 | #endif /* SHA_VERSION */ | |||
1093 | ||||
1094 | /* | |||
1095 | The prototype SHA sub-round | |||
1096 | ||||
1097 | The fundamental sub-round is | |||
1098 | a' = e + ROTL(5, a) + f(b, c, d) + k + data; | |||
1099 | b' = a; | |||
1100 | c' = ROTL(30, b); | |||
1101 | d' = c; | |||
1102 | e' = d; | |||
1103 | ... but this is implemented by unrolling the loop 5 times and renaming | |||
1104 | the variables (e, a, b, c, d) = (a', b', c', d', e') each iteration. | |||
1105 | */ | |||
1106 | #define subRound(a, b, c, d, e, f, k, data)( (e) += ( (((a)) << (5u)) | (((a)) >> (32-(5u))) ) + f((b), (c), (d)) + (k) + (data), (b) = ( (((b)) << (30u)) | (((b)) >> (32-(30u))) ) ) \ | |||
1107 | ( (e) += ROTL(5u, (a))( (((a)) << (5u)) | (((a)) >> (32-(5u))) ) + f((b), (c), (d)) + (k) + (data), (b) = ROTL(30u, (b))( (((b)) << (30u)) | (((b)) >> (32-(30u))) ) ) | |||
1108 | /* | |||
1109 | * The above code is replicated 20 times for each of the 4 functions, | |||
1110 | * using the next 20 values from the W[] array for "data" each time. | |||
1111 | */ | |||
1112 | ||||
1113 | /* | |||
1114 | * Perform the SHA transformation. Note that this code, like MD5, seems to | |||
1115 | * break some optimizing compilers due to the complexity of the expressions | |||
1116 | * and the size of the basic block. It may be necessary to split it into | |||
1117 | * sections, e.g. based on the four sub-rounds | |||
1118 | * | |||
1119 | * Note that this corrupts the sha->key area. | |||
1120 | */ | |||
1121 | ||||
1122 | static void | |||
1123 | SHATransform(Ns_CtxSHA1 *sha) | |||
1124 | { | |||
1125 | register uint32_t A, B, C, D, E; | |||
1126 | #if SHA_VERSION1 | |||
1127 | register uint32_t t; | |||
1128 | #endif | |||
1129 | ||||
1130 | NS_NONNULL_ASSERT(sha != NULL)((void) (0)); | |||
1131 | ||||
1132 | /* | |||
1133 | * Set up first buffer | |||
1134 | */ | |||
1135 | A = sha->iv[0]; | |||
1136 | B = sha->iv[1]; | |||
1137 | C = sha->iv[2]; | |||
1138 | D = sha->iv[3]; | |||
1139 | E = sha->iv[4]; | |||
1140 | ||||
1141 | /* | |||
1142 | * Heavy mangling, in 4 sub-rounds of 20 interactions each. | |||
1143 | */ | |||
1144 | subRound (A, B, C, D, E, f1, K2, sha->key[0])( (E) += ( (((A)) << (5u)) | (((A)) >> (32-(5u))) ) + ( ((D)) ^ (((B)) & (((C)) ^ ((D))) ) ) + ((0x5A827999u )) + (sha->key[0]), (B) = ( (((B)) << (30u)) | (((B) ) >> (32-(30u))) ) ); | |||
1145 | subRound (E, A, B, C, D, f1, K2, sha->key[1])( (D) += ( (((E)) << (5u)) | (((E)) >> (32-(5u))) ) + ( ((C)) ^ (((A)) & (((B)) ^ ((C))) ) ) + ((0x5A827999u )) + (sha->key[1]), (A) = ( (((A)) << (30u)) | (((A) ) >> (32-(30u))) ) ); | |||
1146 | subRound (D, E, A, B, C, f1, K2, sha->key[2])( (C) += ( (((D)) << (5u)) | (((D)) >> (32-(5u))) ) + ( ((B)) ^ (((E)) & (((A)) ^ ((B))) ) ) + ((0x5A827999u )) + (sha->key[2]), (E) = ( (((E)) << (30u)) | (((E) ) >> (32-(30u))) ) ); | |||
1147 | subRound (C, D, E, A, B, f1, K2, sha->key[3])( (B) += ( (((C)) << (5u)) | (((C)) >> (32-(5u))) ) + ( ((A)) ^ (((D)) & (((E)) ^ ((A))) ) ) + ((0x5A827999u )) + (sha->key[3]), (D) = ( (((D)) << (30u)) | (((D) ) >> (32-(30u))) ) ); | |||
1148 | subRound (B, C, D, E, A, f1, K2, sha->key[4])( (A) += ( (((B)) << (5u)) | (((B)) >> (32-(5u))) ) + ( ((E)) ^ (((C)) & (((D)) ^ ((E))) ) ) + ((0x5A827999u )) + (sha->key[4]), (C) = ( (((C)) << (30u)) | (((C) ) >> (32-(30u))) ) ); | |||
1149 | subRound (A, B, C, D, E, f1, K2, sha->key[5])( (E) += ( (((A)) << (5u)) | (((A)) >> (32-(5u))) ) + ( ((D)) ^ (((B)) & (((C)) ^ ((D))) ) ) + ((0x5A827999u )) + (sha->key[5]), (B) = ( (((B)) << (30u)) | (((B) ) >> (32-(30u))) ) ); | |||
1150 | subRound (E, A, B, C, D, f1, K2, sha->key[6])( (D) += ( (((E)) << (5u)) | (((E)) >> (32-(5u))) ) + ( ((C)) ^ (((A)) & (((B)) ^ ((C))) ) ) + ((0x5A827999u )) + (sha->key[6]), (A) = ( (((A)) << (30u)) | (((A) ) >> (32-(30u))) ) ); | |||
1151 | subRound (D, E, A, B, C, f1, K2, sha->key[7])( (C) += ( (((D)) << (5u)) | (((D)) >> (32-(5u))) ) + ( ((B)) ^ (((E)) & (((A)) ^ ((B))) ) ) + ((0x5A827999u )) + (sha->key[7]), (E) = ( (((E)) << (30u)) | (((E) ) >> (32-(30u))) ) ); | |||
1152 | subRound (C, D, E, A, B, f1, K2, sha->key[8])( (B) += ( (((C)) << (5u)) | (((C)) >> (32-(5u))) ) + ( ((A)) ^ (((D)) & (((E)) ^ ((A))) ) ) + ((0x5A827999u )) + (sha->key[8]), (D) = ( (((D)) << (30u)) | (((D) ) >> (32-(30u))) ) ); | |||
1153 | subRound (B, C, D, E, A, f1, K2, sha->key[9])( (A) += ( (((B)) << (5u)) | (((B)) >> (32-(5u))) ) + ( ((E)) ^ (((C)) & (((D)) ^ ((E))) ) ) + ((0x5A827999u )) + (sha->key[9]), (C) = ( (((C)) << (30u)) | (((C) ) >> (32-(30u))) ) ); | |||
1154 | subRound (A, B, C, D, E, f1, K2, sha->key[10])( (E) += ( (((A)) << (5u)) | (((A)) >> (32-(5u))) ) + ( ((D)) ^ (((B)) & (((C)) ^ ((D))) ) ) + ((0x5A827999u )) + (sha->key[10]), (B) = ( (((B)) << (30u)) | (((B )) >> (32-(30u))) ) ); | |||
1155 | subRound (E, A, B, C, D, f1, K2, sha->key[11])( (D) += ( (((E)) << (5u)) | (((E)) >> (32-(5u))) ) + ( ((C)) ^ (((A)) & (((B)) ^ ((C))) ) ) + ((0x5A827999u )) + (sha->key[11]), (A) = ( (((A)) << (30u)) | (((A )) >> (32-(30u))) ) ); | |||
1156 | subRound (D, E, A, B, C, f1, K2, sha->key[12])( (C) += ( (((D)) << (5u)) | (((D)) >> (32-(5u))) ) + ( ((B)) ^ (((E)) & (((A)) ^ ((B))) ) ) + ((0x5A827999u )) + (sha->key[12]), (E) = ( (((E)) << (30u)) | (((E )) >> (32-(30u))) ) ); | |||
1157 | subRound (C, D, E, A, B, f1, K2, sha->key[13])( (B) += ( (((C)) << (5u)) | (((C)) >> (32-(5u))) ) + ( ((A)) ^ (((D)) & (((E)) ^ ((A))) ) ) + ((0x5A827999u )) + (sha->key[13]), (D) = ( (((D)) << (30u)) | (((D )) >> (32-(30u))) ) ); | |||
1158 | subRound (B, C, D, E, A, f1, K2, sha->key[14])( (A) += ( (((B)) << (5u)) | (((B)) >> (32-(5u))) ) + ( ((E)) ^ (((C)) & (((D)) ^ ((E))) ) ) + ((0x5A827999u )) + (sha->key[14]), (C) = ( (((C)) << (30u)) | (((C )) >> (32-(30u))) ) ); | |||
1159 | subRound (A, B, C, D, E, f1, K2, sha->key[15])( (E) += ( (((A)) << (5u)) | (((A)) >> (32-(5u))) ) + ( ((D)) ^ (((B)) & (((C)) ^ ((D))) ) ) + ((0x5A827999u )) + (sha->key[15]), (B) = ( (((B)) << (30u)) | (((B )) >> (32-(30u))) ) ); | |||
1160 | subRound (E, A, B, C, D, f1, K2, expand (sha->key, 16u))( (D) += ( (((E)) << (5u)) | (((E)) >> (32-(5u))) ) + ( ((C)) ^ (((A)) & (((B)) ^ ((C))) ) ) + ((0x5A827999u )) + ((sha->key[(16u)&15u] = (t = sha->key[((16u))& 15u] ^ sha->key[(((16u))-14)&15u] ^ sha->key[(((16u ))-8)&15u] ^ sha->key[(((16u))-3)&15u], ( ((t) << (1)) | ((t) >> (32-(1))) )))), (A) = ( (((A)) << (30u)) | (((A)) >> (32-(30u))) ) ); | |||
1161 | subRound (D, E, A, B, C, f1, K2, expand (sha->key, 17u))( (C) += ( (((D)) << (5u)) | (((D)) >> (32-(5u))) ) + ( ((B)) ^ (((E)) & (((A)) ^ ((B))) ) ) + ((0x5A827999u )) + ((sha->key[(17u)&15u] = (t = sha->key[((17u))& 15u] ^ sha->key[(((17u))-14)&15u] ^ sha->key[(((17u ))-8)&15u] ^ sha->key[(((17u))-3)&15u], ( ((t) << (1)) | ((t) >> (32-(1))) )))), (E) = ( (((E)) << (30u)) | (((E)) >> (32-(30u))) ) ); | |||
1162 | subRound (C, D, E, A, B, f1, K2, expand (sha->key, 18u))( (B) += ( (((C)) << (5u)) | (((C)) >> (32-(5u))) ) + ( ((A)) ^ (((D)) & (((E)) ^ ((A))) ) ) + ((0x5A827999u )) + ((sha->key[(18u)&15u] = (t = sha->key[((18u))& 15u] ^ sha->key[(((18u))-14)&15u] ^ sha->key[(((18u ))-8)&15u] ^ sha->key[(((18u))-3)&15u], ( ((t) << (1)) | ((t) >> (32-(1))) )))), (D) = ( (((D)) << (30u)) | (((D)) >> (32-(30u))) ) ); | |||
1163 | subRound (B, C, D, E, A, f1, K2, expand (sha->key, 19u))( (A) += ( (((B)) << (5u)) | (((B)) >> (32-(5u))) ) + ( ((E)) ^ (((C)) & (((D)) ^ ((E))) ) ) + ((0x5A827999u )) + ((sha->key[(19u)&15u] = (t = sha->key[((19u))& 15u] ^ sha->key[(((19u))-14)&15u] ^ sha->key[(((19u ))-8)&15u] ^ sha->key[(((19u))-3)&15u], ( ((t) << (1)) | ((t) >> (32-(1))) )))), (C) = ( (((C)) << (30u)) | (((C)) >> (32-(30u))) ) ); | |||
1164 | ||||
1165 | subRound (A, B, C, D, E, f2, K3, expand (sha->key, 20u))( (E) += ( (((A)) << (5u)) | (((A)) >> (32-(5u))) ) + ( ((B)) ^ ((C)) ^ ((D)) ) + ((0x6ED9EBA1u)) + ((sha-> key[(20u)&15u] = (t = sha->key[((20u))&15u] ^ sha-> key[(((20u))-14)&15u] ^ sha->key[(((20u))-8)&15u] ^ sha->key[(((20u))-3)&15u], ( ((t) << (1)) | ((t ) >> (32-(1))) )))), (B) = ( (((B)) << (30u)) | ( ((B)) >> (32-(30u))) ) ); | |||
1166 | subRound (E, A, B, C, D, f2, K3, expand (sha->key, 21u))( (D) += ( (((E)) << (5u)) | (((E)) >> (32-(5u))) ) + ( ((A)) ^ ((B)) ^ ((C)) ) + ((0x6ED9EBA1u)) + ((sha-> key[(21u)&15u] = (t = sha->key[((21u))&15u] ^ sha-> key[(((21u))-14)&15u] ^ sha->key[(((21u))-8)&15u] ^ sha->key[(((21u))-3)&15u], ( ((t) << (1)) | ((t ) >> (32-(1))) )))), (A) = ( (((A)) << (30u)) | ( ((A)) >> (32-(30u))) ) ); | |||
1167 | subRound (D, E, A, B, C, f2, K3, expand (sha->key, 22u))( (C) += ( (((D)) << (5u)) | (((D)) >> (32-(5u))) ) + ( ((E)) ^ ((A)) ^ ((B)) ) + ((0x6ED9EBA1u)) + ((sha-> key[(22u)&15u] = (t = sha->key[((22u))&15u] ^ sha-> key[(((22u))-14)&15u] ^ sha->key[(((22u))-8)&15u] ^ sha->key[(((22u))-3)&15u], ( ((t) << (1)) | ((t ) >> (32-(1))) )))), (E) = ( (((E)) << (30u)) | ( ((E)) >> (32-(30u))) ) ); | |||
1168 | subRound (C, D, E, A, B, f2, K3, expand (sha->key, 23u))( (B) += ( (((C)) << (5u)) | (((C)) >> (32-(5u))) ) + ( ((D)) ^ ((E)) ^ ((A)) ) + ((0x6ED9EBA1u)) + ((sha-> key[(23u)&15u] = (t = sha->key[((23u))&15u] ^ sha-> key[(((23u))-14)&15u] ^ sha->key[(((23u))-8)&15u] ^ sha->key[(((23u))-3)&15u], ( ((t) << (1)) | ((t ) >> (32-(1))) )))), (D) = ( (((D)) << (30u)) | ( ((D)) >> (32-(30u))) ) ); | |||
1169 | subRound (B, C, D, E, A, f2, K3, expand (sha->key, 24u))( (A) += ( (((B)) << (5u)) | (((B)) >> (32-(5u))) ) + ( ((C)) ^ ((D)) ^ ((E)) ) + ((0x6ED9EBA1u)) + ((sha-> key[(24u)&15u] = (t = sha->key[((24u))&15u] ^ sha-> key[(((24u))-14)&15u] ^ sha->key[(((24u))-8)&15u] ^ sha->key[(((24u))-3)&15u], ( ((t) << (1)) | ((t ) >> (32-(1))) )))), (C) = ( (((C)) << (30u)) | ( ((C)) >> (32-(30u))) ) ); | |||
1170 | subRound (A, B, C, D, E, f2, K3, expand (sha->key, 25u))( (E) += ( (((A)) << (5u)) | (((A)) >> (32-(5u))) ) + ( ((B)) ^ ((C)) ^ ((D)) ) + ((0x6ED9EBA1u)) + ((sha-> key[(25u)&15u] = (t = sha->key[((25u))&15u] ^ sha-> key[(((25u))-14)&15u] ^ sha->key[(((25u))-8)&15u] ^ sha->key[(((25u))-3)&15u], ( ((t) << (1)) | ((t ) >> (32-(1))) )))), (B) = ( (((B)) << (30u)) | ( ((B)) >> (32-(30u))) ) ); | |||
1171 | subRound (E, A, B, C, D, f2, K3, expand (sha->key, 26u))( (D) += ( (((E)) << (5u)) | (((E)) >> (32-(5u))) ) + ( ((A)) ^ ((B)) ^ ((C)) ) + ((0x6ED9EBA1u)) + ((sha-> key[(26u)&15u] = (t = sha->key[((26u))&15u] ^ sha-> key[(((26u))-14)&15u] ^ sha->key[(((26u))-8)&15u] ^ sha->key[(((26u))-3)&15u], ( ((t) << (1)) | ((t ) >> (32-(1))) )))), (A) = ( (((A)) << (30u)) | ( ((A)) >> (32-(30u))) ) ); | |||
1172 | subRound (D, E, A, B, C, f2, K3, expand (sha->key, 27u))( (C) += ( (((D)) << (5u)) | (((D)) >> (32-(5u))) ) + ( ((E)) ^ ((A)) ^ ((B)) ) + ((0x6ED9EBA1u)) + ((sha-> key[(27u)&15u] = (t = sha->key[((27u))&15u] ^ sha-> key[(((27u))-14)&15u] ^ sha->key[(((27u))-8)&15u] ^ sha->key[(((27u))-3)&15u], ( ((t) << (1)) | ((t ) >> (32-(1))) )))), (E) = ( (((E)) << (30u)) | ( ((E)) >> (32-(30u))) ) ); | |||
1173 | subRound (C, D, E, A, B, f2, K3, expand (sha->key, 28u))( (B) += ( (((C)) << (5u)) | (((C)) >> (32-(5u))) ) + ( ((D)) ^ ((E)) ^ ((A)) ) + ((0x6ED9EBA1u)) + ((sha-> key[(28u)&15u] = (t = sha->key[((28u))&15u] ^ sha-> key[(((28u))-14)&15u] ^ sha->key[(((28u))-8)&15u] ^ sha->key[(((28u))-3)&15u], ( ((t) << (1)) | ((t ) >> (32-(1))) )))), (D) = ( (((D)) << (30u)) | ( ((D)) >> (32-(30u))) ) ); | |||
1174 | subRound (B, C, D, E, A, f2, K3, expand (sha->key, 29u))( (A) += ( (((B)) << (5u)) | (((B)) >> (32-(5u))) ) + ( ((C)) ^ ((D)) ^ ((E)) ) + ((0x6ED9EBA1u)) + ((sha-> key[(29u)&15u] = (t = sha->key[((29u))&15u] ^ sha-> key[(((29u))-14)&15u] ^ sha->key[(((29u))-8)&15u] ^ sha->key[(((29u))-3)&15u], ( ((t) << (1)) | ((t ) >> (32-(1))) )))), (C) = ( (((C)) << (30u)) | ( ((C)) >> (32-(30u))) ) ); | |||
1175 | subRound (A, B, C, D, E, f2, K3, expand (sha->key, 30u))( (E) += ( (((A)) << (5u)) | (((A)) >> (32-(5u))) ) + ( ((B)) ^ ((C)) ^ ((D)) ) + ((0x6ED9EBA1u)) + ((sha-> key[(30u)&15u] = (t = sha->key[((30u))&15u] ^ sha-> key[(((30u))-14)&15u] ^ sha->key[(((30u))-8)&15u] ^ sha->key[(((30u))-3)&15u], ( ((t) << (1)) | ((t ) >> (32-(1))) )))), (B) = ( (((B)) << (30u)) | ( ((B)) >> (32-(30u))) ) ); | |||
1176 | subRound (E, A, B, C, D, f2, K3, expand (sha->key, 31u))( (D) += ( (((E)) << (5u)) | (((E)) >> (32-(5u))) ) + ( ((A)) ^ ((B)) ^ ((C)) ) + ((0x6ED9EBA1u)) + ((sha-> key[(31u)&15u] = (t = sha->key[((31u))&15u] ^ sha-> key[(((31u))-14)&15u] ^ sha->key[(((31u))-8)&15u] ^ sha->key[(((31u))-3)&15u], ( ((t) << (1)) | ((t ) >> (32-(1))) )))), (A) = ( (((A)) << (30u)) | ( ((A)) >> (32-(30u))) ) ); | |||
1177 | subRound (D, E, A, B, C, f2, K3, expand (sha->key, 32u))( (C) += ( (((D)) << (5u)) | (((D)) >> (32-(5u))) ) + ( ((E)) ^ ((A)) ^ ((B)) ) + ((0x6ED9EBA1u)) + ((sha-> key[(32u)&15u] = (t = sha->key[((32u))&15u] ^ sha-> key[(((32u))-14)&15u] ^ sha->key[(((32u))-8)&15u] ^ sha->key[(((32u))-3)&15u], ( ((t) << (1)) | ((t ) >> (32-(1))) )))), (E) = ( (((E)) << (30u)) | ( ((E)) >> (32-(30u))) ) ); | |||
1178 | subRound (C, D, E, A, B, f2, K3, expand (sha->key, 33u))( (B) += ( (((C)) << (5u)) | (((C)) >> (32-(5u))) ) + ( ((D)) ^ ((E)) ^ ((A)) ) + ((0x6ED9EBA1u)) + ((sha-> key[(33u)&15u] = (t = sha->key[((33u))&15u] ^ sha-> key[(((33u))-14)&15u] ^ sha->key[(((33u))-8)&15u] ^ sha->key[(((33u))-3)&15u], ( ((t) << (1)) | ((t ) >> (32-(1))) )))), (D) = ( (((D)) << (30u)) | ( ((D)) >> (32-(30u))) ) ); | |||
1179 | subRound (B, C, D, E, A, f2, K3, expand (sha->key, 34u))( (A) += ( (((B)) << (5u)) | (((B)) >> (32-(5u))) ) + ( ((C)) ^ ((D)) ^ ((E)) ) + ((0x6ED9EBA1u)) + ((sha-> key[(34u)&15u] = (t = sha->key[((34u))&15u] ^ sha-> key[(((34u))-14)&15u] ^ sha->key[(((34u))-8)&15u] ^ sha->key[(((34u))-3)&15u], ( ((t) << (1)) | ((t ) >> (32-(1))) )))), (C) = ( (((C)) << (30u)) | ( ((C)) >> (32-(30u))) ) ); | |||
1180 | subRound (A, B, C, D, E, f2, K3, expand (sha->key, 35u))( (E) += ( (((A)) << (5u)) | (((A)) >> (32-(5u))) ) + ( ((B)) ^ ((C)) ^ ((D)) ) + ((0x6ED9EBA1u)) + ((sha-> key[(35u)&15u] = (t = sha->key[((35u))&15u] ^ sha-> key[(((35u))-14)&15u] ^ sha->key[(((35u))-8)&15u] ^ sha->key[(((35u))-3)&15u], ( ((t) << (1)) | ((t ) >> (32-(1))) )))), (B) = ( (((B)) << (30u)) | ( ((B)) >> (32-(30u))) ) ); | |||
1181 | subRound (E, A, B, C, D, f2, K3, expand (sha->key, 36u))( (D) += ( (((E)) << (5u)) | (((E)) >> (32-(5u))) ) + ( ((A)) ^ ((B)) ^ ((C)) ) + ((0x6ED9EBA1u)) + ((sha-> key[(36u)&15u] = (t = sha->key[((36u))&15u] ^ sha-> key[(((36u))-14)&15u] ^ sha->key[(((36u))-8)&15u] ^ sha->key[(((36u))-3)&15u], ( ((t) << (1)) | ((t ) >> (32-(1))) )))), (A) = ( (((A)) << (30u)) | ( ((A)) >> (32-(30u))) ) ); | |||
1182 | subRound (D, E, A, B, C, f2, K3, expand (sha->key, 37u))( (C) += ( (((D)) << (5u)) | (((D)) >> (32-(5u))) ) + ( ((E)) ^ ((A)) ^ ((B)) ) + ((0x6ED9EBA1u)) + ((sha-> key[(37u)&15u] = (t = sha->key[((37u))&15u] ^ sha-> key[(((37u))-14)&15u] ^ sha->key[(((37u))-8)&15u] ^ sha->key[(((37u))-3)&15u], ( ((t) << (1)) | ((t ) >> (32-(1))) )))), (E) = ( (((E)) << (30u)) | ( ((E)) >> (32-(30u))) ) ); | |||
1183 | subRound (C, D, E, A, B, f2, K3, expand (sha->key, 38u))( (B) += ( (((C)) << (5u)) | (((C)) >> (32-(5u))) ) + ( ((D)) ^ ((E)) ^ ((A)) ) + ((0x6ED9EBA1u)) + ((sha-> key[(38u)&15u] = (t = sha->key[((38u))&15u] ^ sha-> key[(((38u))-14)&15u] ^ sha->key[(((38u))-8)&15u] ^ sha->key[(((38u))-3)&15u], ( ((t) << (1)) | ((t ) >> (32-(1))) )))), (D) = ( (((D)) << (30u)) | ( ((D)) >> (32-(30u))) ) ); | |||
1184 | subRound (B, C, D, E, A, f2, K3, expand (sha->key, 39u))( (A) += ( (((B)) << (5u)) | (((B)) >> (32-(5u))) ) + ( ((C)) ^ ((D)) ^ ((E)) ) + ((0x6ED9EBA1u)) + ((sha-> key[(39u)&15u] = (t = sha->key[((39u))&15u] ^ sha-> key[(((39u))-14)&15u] ^ sha->key[(((39u))-8)&15u] ^ sha->key[(((39u))-3)&15u], ( ((t) << (1)) | ((t ) >> (32-(1))) )))), (C) = ( (((C)) << (30u)) | ( ((C)) >> (32-(30u))) ) ); | |||
1185 | ||||
1186 | subRound (A, B, C, D, E, f3, K5, expand (sha->key, 40u))( (E) += ( (((A)) << (5u)) | (((A)) >> (32-(5u))) ) + ( (((B)) & ((C))) + (((D)) & (((B)) ^ ((C))) ) ) + ((0x8F1BBCDCu)) + ((sha->key[(40u)&15u] = (t = sha-> key[((40u))&15u] ^ sha->key[(((40u))-14)&15u] ^ sha ->key[(((40u))-8)&15u] ^ sha->key[(((40u))-3)&15u ], ( ((t) << (1)) | ((t) >> (32-(1))) )))), (B) = ( (((B)) << (30u)) | (((B)) >> (32-(30u))) ) ); | |||
1187 | subRound (E, A, B, C, D, f3, K5, expand (sha->key, 41u))( (D) += ( (((E)) << (5u)) | (((E)) >> (32-(5u))) ) + ( (((A)) & ((B))) + (((C)) & (((A)) ^ ((B))) ) ) + ((0x8F1BBCDCu)) + ((sha->key[(41u)&15u] = (t = sha-> key[((41u))&15u] ^ sha->key[(((41u))-14)&15u] ^ sha ->key[(((41u))-8)&15u] ^ sha->key[(((41u))-3)&15u ], ( ((t) << (1)) | ((t) >> (32-(1))) )))), (A) = ( (((A)) << (30u)) | (((A)) >> (32-(30u))) ) ); | |||
1188 | subRound (D, E, A, B, C, f3, K5, expand (sha->key, 42u))( (C) += ( (((D)) << (5u)) | (((D)) >> (32-(5u))) ) + ( (((E)) & ((A))) + (((B)) & (((E)) ^ ((A))) ) ) + ((0x8F1BBCDCu)) + ((sha->key[(42u)&15u] = (t = sha-> key[((42u))&15u] ^ sha->key[(((42u))-14)&15u] ^ sha ->key[(((42u))-8)&15u] ^ sha->key[(((42u))-3)&15u ], ( ((t) << (1)) | ((t) >> (32-(1))) )))), (E) = ( (((E)) << (30u)) | (((E)) >> (32-(30u))) ) ); | |||
1189 | subRound (C, D, E, A, B, f3, K5, expand (sha->key, 43u))( (B) += ( (((C)) << (5u)) | (((C)) >> (32-(5u))) ) + ( (((D)) & ((E))) + (((A)) & (((D)) ^ ((E))) ) ) + ((0x8F1BBCDCu)) + ((sha->key[(43u)&15u] = (t = sha-> key[((43u))&15u] ^ sha->key[(((43u))-14)&15u] ^ sha ->key[(((43u))-8)&15u] ^ sha->key[(((43u))-3)&15u ], ( ((t) << (1)) | ((t) >> (32-(1))) )))), (D) = ( (((D)) << (30u)) | (((D)) >> (32-(30u))) ) ); | |||
1190 | subRound (B, C, D, E, A, f3, K5, expand (sha->key, 44u))( (A) += ( (((B)) << (5u)) | (((B)) >> (32-(5u))) ) + ( (((C)) & ((D))) + (((E)) & (((C)) ^ ((D))) ) ) + ((0x8F1BBCDCu)) + ((sha->key[(44u)&15u] = (t = sha-> key[((44u))&15u] ^ sha->key[(((44u))-14)&15u] ^ sha ->key[(((44u))-8)&15u] ^ sha->key[(((44u))-3)&15u ], ( ((t) << (1)) | ((t) >> (32-(1))) )))), (C) = ( (((C)) << (30u)) | (((C)) >> (32-(30u))) ) ); | |||
1191 | subRound (A, B, C, D, E, f3, K5, expand (sha->key, 45u))( (E) += ( (((A)) << (5u)) | (((A)) >> (32-(5u))) ) + ( (((B)) & ((C))) + (((D)) & (((B)) ^ ((C))) ) ) + ((0x8F1BBCDCu)) + ((sha->key[(45u)&15u] = (t = sha-> key[((45u))&15u] ^ sha->key[(((45u))-14)&15u] ^ sha ->key[(((45u))-8)&15u] ^ sha->key[(((45u))-3)&15u ], ( ((t) << (1)) | ((t) >> (32-(1))) )))), (B) = ( (((B)) << (30u)) | (((B)) >> (32-(30u))) ) ); | |||
1192 | subRound (E, A, B, C, D, f3, K5, expand (sha->key, 46u))( (D) += ( (((E)) << (5u)) | (((E)) >> (32-(5u))) ) + ( (((A)) & ((B))) + (((C)) & (((A)) ^ ((B))) ) ) + ((0x8F1BBCDCu)) + ((sha->key[(46u)&15u] = (t = sha-> key[((46u))&15u] ^ sha->key[(((46u))-14)&15u] ^ sha ->key[(((46u))-8)&15u] ^ sha->key[(((46u))-3)&15u ], ( ((t) << (1)) | ((t) >> (32-(1))) )))), (A) = ( (((A)) << (30u)) | (((A)) >> (32-(30u))) ) ); | |||
1193 | subRound (D, E, A, B, C, f3, K5, expand (sha->key, 47u))( (C) += ( (((D)) << (5u)) | (((D)) >> (32-(5u))) ) + ( (((E)) & ((A))) + (((B)) & (((E)) ^ ((A))) ) ) + ((0x8F1BBCDCu)) + ((sha->key[(47u)&15u] = (t = sha-> key[((47u))&15u] ^ sha->key[(((47u))-14)&15u] ^ sha ->key[(((47u))-8)&15u] ^ sha->key[(((47u))-3)&15u ], ( ((t) << (1)) | ((t) >> (32-(1))) )))), (E) = ( (((E)) << (30u)) | (((E)) >> (32-(30u))) ) ); | |||
1194 | subRound (C, D, E, A, B, f3, K5, expand (sha->key, 48u))( (B) += ( (((C)) << (5u)) | (((C)) >> (32-(5u))) ) + ( (((D)) & ((E))) + (((A)) & (((D)) ^ ((E))) ) ) + ((0x8F1BBCDCu)) + ((sha->key[(48u)&15u] = (t = sha-> key[((48u))&15u] ^ sha->key[(((48u))-14)&15u] ^ sha ->key[(((48u))-8)&15u] ^ sha->key[(((48u))-3)&15u ], ( ((t) << (1)) | ((t) >> (32-(1))) )))), (D) = ( (((D)) << (30u)) | (((D)) >> (32-(30u))) ) ); | |||
1195 | subRound (B, C, D, E, A, f3, K5, expand (sha->key, 49u))( (A) += ( (((B)) << (5u)) | (((B)) >> (32-(5u))) ) + ( (((C)) & ((D))) + (((E)) & (((C)) ^ ((D))) ) ) + ((0x8F1BBCDCu)) + ((sha->key[(49u)&15u] = (t = sha-> key[((49u))&15u] ^ sha->key[(((49u))-14)&15u] ^ sha ->key[(((49u))-8)&15u] ^ sha->key[(((49u))-3)&15u ], ( ((t) << (1)) | ((t) >> (32-(1))) )))), (C) = ( (((C)) << (30u)) | (((C)) >> (32-(30u))) ) ); | |||
1196 | subRound (A, B, C, D, E, f3, K5, expand (sha->key, 50u))( (E) += ( (((A)) << (5u)) | (((A)) >> (32-(5u))) ) + ( (((B)) & ((C))) + (((D)) & (((B)) ^ ((C))) ) ) + ((0x8F1BBCDCu)) + ((sha->key[(50u)&15u] = (t = sha-> key[((50u))&15u] ^ sha->key[(((50u))-14)&15u] ^ sha ->key[(((50u))-8)&15u] ^ sha->key[(((50u))-3)&15u ], ( ((t) << (1)) | ((t) >> (32-(1))) )))), (B) = ( (((B)) << (30u)) | (((B)) >> (32-(30u))) ) ); | |||
1197 | subRound (E, A, B, C, D, f3, K5, expand (sha->key, 51u))( (D) += ( (((E)) << (5u)) | (((E)) >> (32-(5u))) ) + ( (((A)) & ((B))) + (((C)) & (((A)) ^ ((B))) ) ) + ((0x8F1BBCDCu)) + ((sha->key[(51u)&15u] = (t = sha-> key[((51u))&15u] ^ sha->key[(((51u))-14)&15u] ^ sha ->key[(((51u))-8)&15u] ^ sha->key[(((51u))-3)&15u ], ( ((t) << (1)) | ((t) >> (32-(1))) )))), (A) = ( (((A)) << (30u)) | (((A)) >> (32-(30u))) ) ); | |||
1198 | subRound (D, E, A, B, C, f3, K5, expand (sha->key, 52u))( (C) += ( (((D)) << (5u)) | (((D)) >> (32-(5u))) ) + ( (((E)) & ((A))) + (((B)) & (((E)) ^ ((A))) ) ) + ((0x8F1BBCDCu)) + ((sha->key[(52u)&15u] = (t = sha-> key[((52u))&15u] ^ sha->key[(((52u))-14)&15u] ^ sha ->key[(((52u))-8)&15u] ^ sha->key[(((52u))-3)&15u ], ( ((t) << (1)) | ((t) >> (32-(1))) )))), (E) = ( (((E)) << (30u)) | (((E)) >> (32-(30u))) ) ); | |||
1199 | subRound (C, D, E, A, B, f3, K5, expand (sha->key, 53u))( (B) += ( (((C)) << (5u)) | (((C)) >> (32-(5u))) ) + ( (((D)) & ((E))) + (((A)) & (((D)) ^ ((E))) ) ) + ((0x8F1BBCDCu)) + ((sha->key[(53u)&15u] = (t = sha-> key[((53u))&15u] ^ sha->key[(((53u))-14)&15u] ^ sha ->key[(((53u))-8)&15u] ^ sha->key[(((53u))-3)&15u ], ( ((t) << (1)) | ((t) >> (32-(1))) )))), (D) = ( (((D)) << (30u)) | (((D)) >> (32-(30u))) ) ); | |||
1200 | subRound (B, C, D, E, A, f3, K5, expand (sha->key, 54u))( (A) += ( (((B)) << (5u)) | (((B)) >> (32-(5u))) ) + ( (((C)) & ((D))) + (((E)) & (((C)) ^ ((D))) ) ) + ((0x8F1BBCDCu)) + ((sha->key[(54u)&15u] = (t = sha-> key[((54u))&15u] ^ sha->key[(((54u))-14)&15u] ^ sha ->key[(((54u))-8)&15u] ^ sha->key[(((54u))-3)&15u ], ( ((t) << (1)) | ((t) >> (32-(1))) )))), (C) = ( (((C)) << (30u)) | (((C)) >> (32-(30u))) ) ); | |||
1201 | subRound (A, B, C, D, E, f3, K5, expand (sha->key, 55u))( (E) += ( (((A)) << (5u)) | (((A)) >> (32-(5u))) ) + ( (((B)) & ((C))) + (((D)) & (((B)) ^ ((C))) ) ) + ((0x8F1BBCDCu)) + ((sha->key[(55u)&15u] = (t = sha-> key[((55u))&15u] ^ sha->key[(((55u))-14)&15u] ^ sha ->key[(((55u))-8)&15u] ^ sha->key[(((55u))-3)&15u ], ( ((t) << (1)) | ((t) >> (32-(1))) )))), (B) = ( (((B)) << (30u)) | (((B)) >> (32-(30u))) ) ); | |||
1202 | subRound (E, A, B, C, D, f3, K5, expand (sha->key, 56u))( (D) += ( (((E)) << (5u)) | (((E)) >> (32-(5u))) ) + ( (((A)) & ((B))) + (((C)) & (((A)) ^ ((B))) ) ) + ((0x8F1BBCDCu)) + ((sha->key[(56u)&15u] = (t = sha-> key[((56u))&15u] ^ sha->key[(((56u))-14)&15u] ^ sha ->key[(((56u))-8)&15u] ^ sha->key[(((56u))-3)&15u ], ( ((t) << (1)) | ((t) >> (32-(1))) )))), (A) = ( (((A)) << (30u)) | (((A)) >> (32-(30u))) ) ); | |||
1203 | subRound (D, E, A, B, C, f3, K5, expand (sha->key, 57u))( (C) += ( (((D)) << (5u)) | (((D)) >> (32-(5u))) ) + ( (((E)) & ((A))) + (((B)) & (((E)) ^ ((A))) ) ) + ((0x8F1BBCDCu)) + ((sha->key[(57u)&15u] = (t = sha-> key[((57u))&15u] ^ sha->key[(((57u))-14)&15u] ^ sha ->key[(((57u))-8)&15u] ^ sha->key[(((57u))-3)&15u ], ( ((t) << (1)) | ((t) >> (32-(1))) )))), (E) = ( (((E)) << (30u)) | (((E)) >> (32-(30u))) ) ); | |||
1204 | subRound (C, D, E, A, B, f3, K5, expand (sha->key, 58u))( (B) += ( (((C)) << (5u)) | (((C)) >> (32-(5u))) ) + ( (((D)) & ((E))) + (((A)) & (((D)) ^ ((E))) ) ) + ((0x8F1BBCDCu)) + ((sha->key[(58u)&15u] = (t = sha-> key[((58u))&15u] ^ sha->key[(((58u))-14)&15u] ^ sha ->key[(((58u))-8)&15u] ^ sha->key[(((58u))-3)&15u ], ( ((t) << (1)) | ((t) >> (32-(1))) )))), (D) = ( (((D)) << (30u)) | (((D)) >> (32-(30u))) ) ); | |||
1205 | subRound (B, C, D, E, A, f3, K5, expand (sha->key, 59u))( (A) += ( (((B)) << (5u)) | (((B)) >> (32-(5u))) ) + ( (((C)) & ((D))) + (((E)) & (((C)) ^ ((D))) ) ) + ((0x8F1BBCDCu)) + ((sha->key[(59u)&15u] = (t = sha-> key[((59u))&15u] ^ sha->key[(((59u))-14)&15u] ^ sha ->key[(((59u))-8)&15u] ^ sha->key[(((59u))-3)&15u ], ( ((t) << (1)) | ((t) >> (32-(1))) )))), (C) = ( (((C)) << (30u)) | (((C)) >> (32-(30u))) ) ); | |||
1206 | ||||
1207 | subRound (A, B, C, D, E, f4, K10, expand (sha->key, 60u))( (E) += ( (((A)) << (5u)) | (((A)) >> (32-(5u))) ) + ( ((B)) ^ ((C)) ^ ((D)) ) + ((0xCA62C1D6u)) + ((sha-> key[(60u)&15u] = (t = sha->key[((60u))&15u] ^ sha-> key[(((60u))-14)&15u] ^ sha->key[(((60u))-8)&15u] ^ sha->key[(((60u))-3)&15u], ( ((t) << (1)) | ((t ) >> (32-(1))) )))), (B) = ( (((B)) << (30u)) | ( ((B)) >> (32-(30u))) ) ); | |||
1208 | subRound (E, A, B, C, D, f4, K10, expand (sha->key, 61u))( (D) += ( (((E)) << (5u)) | (((E)) >> (32-(5u))) ) + ( ((A)) ^ ((B)) ^ ((C)) ) + ((0xCA62C1D6u)) + ((sha-> key[(61u)&15u] = (t = sha->key[((61u))&15u] ^ sha-> key[(((61u))-14)&15u] ^ sha->key[(((61u))-8)&15u] ^ sha->key[(((61u))-3)&15u], ( ((t) << (1)) | ((t ) >> (32-(1))) )))), (A) = ( (((A)) << (30u)) | ( ((A)) >> (32-(30u))) ) ); | |||
1209 | subRound (D, E, A, B, C, f4, K10, expand (sha->key, 62u))( (C) += ( (((D)) << (5u)) | (((D)) >> (32-(5u))) ) + ( ((E)) ^ ((A)) ^ ((B)) ) + ((0xCA62C1D6u)) + ((sha-> key[(62u)&15u] = (t = sha->key[((62u))&15u] ^ sha-> key[(((62u))-14)&15u] ^ sha->key[(((62u))-8)&15u] ^ sha->key[(((62u))-3)&15u], ( ((t) << (1)) | ((t ) >> (32-(1))) )))), (E) = ( (((E)) << (30u)) | ( ((E)) >> (32-(30u))) ) ); | |||
1210 | subRound (C, D, E, A, B, f4, K10, expand (sha->key, 63u))( (B) += ( (((C)) << (5u)) | (((C)) >> (32-(5u))) ) + ( ((D)) ^ ((E)) ^ ((A)) ) + ((0xCA62C1D6u)) + ((sha-> key[(63u)&15u] = (t = sha->key[((63u))&15u] ^ sha-> key[(((63u))-14)&15u] ^ sha->key[(((63u))-8)&15u] ^ sha->key[(((63u))-3)&15u], ( ((t) << (1)) | ((t ) >> (32-(1))) )))), (D) = ( (((D)) << (30u)) | ( ((D)) >> (32-(30u))) ) ); | |||
1211 | subRound (B, C, D, E, A, f4, K10, expand (sha->key, 64u))( (A) += ( (((B)) << (5u)) | (((B)) >> (32-(5u))) ) + ( ((C)) ^ ((D)) ^ ((E)) ) + ((0xCA62C1D6u)) + ((sha-> key[(64u)&15u] = (t = sha->key[((64u))&15u] ^ sha-> key[(((64u))-14)&15u] ^ sha->key[(((64u))-8)&15u] ^ sha->key[(((64u))-3)&15u], ( ((t) << (1)) | ((t ) >> (32-(1))) )))), (C) = ( (((C)) << (30u)) | ( ((C)) >> (32-(30u))) ) ); | |||
1212 | subRound (A, B, C, D, E, f4, K10, expand (sha->key, 65u))( (E) += ( (((A)) << (5u)) | (((A)) >> (32-(5u))) ) + ( ((B)) ^ ((C)) ^ ((D)) ) + ((0xCA62C1D6u)) + ((sha-> key[(65u)&15u] = (t = sha->key[((65u))&15u] ^ sha-> key[(((65u))-14)&15u] ^ sha->key[(((65u))-8)&15u] ^ sha->key[(((65u))-3)&15u], ( ((t) << (1)) | ((t ) >> (32-(1))) )))), (B) = ( (((B)) << (30u)) | ( ((B)) >> (32-(30u))) ) ); | |||
1213 | subRound (E, A, B, C, D, f4, K10, expand (sha->key, 66u))( (D) += ( (((E)) << (5u)) | (((E)) >> (32-(5u))) ) + ( ((A)) ^ ((B)) ^ ((C)) ) + ((0xCA62C1D6u)) + ((sha-> key[(66u)&15u] = (t = sha->key[((66u))&15u] ^ sha-> key[(((66u))-14)&15u] ^ sha->key[(((66u))-8)&15u] ^ sha->key[(((66u))-3)&15u], ( ((t) << (1)) | ((t ) >> (32-(1))) )))), (A) = ( (((A)) << (30u)) | ( ((A)) >> (32-(30u))) ) ); | |||
1214 | subRound (D, E, A, B, C, f4, K10, expand (sha->key, 67u))( (C) += ( (((D)) << (5u)) | (((D)) >> (32-(5u))) ) + ( ((E)) ^ ((A)) ^ ((B)) ) + ((0xCA62C1D6u)) + ((sha-> key[(67u)&15u] = (t = sha->key[((67u))&15u] ^ sha-> key[(((67u))-14)&15u] ^ sha->key[(((67u))-8)&15u] ^ sha->key[(((67u))-3)&15u], ( ((t) << (1)) | ((t ) >> (32-(1))) )))), (E) = ( (((E)) << (30u)) | ( ((E)) >> (32-(30u))) ) ); | |||
1215 | subRound (C, D, E, A, B, f4, K10, expand (sha->key, 68u))( (B) += ( (((C)) << (5u)) | (((C)) >> (32-(5u))) ) + ( ((D)) ^ ((E)) ^ ((A)) ) + ((0xCA62C1D6u)) + ((sha-> key[(68u)&15u] = (t = sha->key[((68u))&15u] ^ sha-> key[(((68u))-14)&15u] ^ sha->key[(((68u))-8)&15u] ^ sha->key[(((68u))-3)&15u], ( ((t) << (1)) | ((t ) >> (32-(1))) )))), (D) = ( (((D)) << (30u)) | ( ((D)) >> (32-(30u))) ) ); | |||
1216 | subRound (B, C, D, E, A, f4, K10, expand (sha->key, 69u))( (A) += ( (((B)) << (5u)) | (((B)) >> (32-(5u))) ) + ( ((C)) ^ ((D)) ^ ((E)) ) + ((0xCA62C1D6u)) + ((sha-> key[(69u)&15u] = (t = sha->key[((69u))&15u] ^ sha-> key[(((69u))-14)&15u] ^ sha->key[(((69u))-8)&15u] ^ sha->key[(((69u))-3)&15u], ( ((t) << (1)) | ((t ) >> (32-(1))) )))), (C) = ( (((C)) << (30u)) | ( ((C)) >> (32-(30u))) ) ); | |||
1217 | subRound (A, B, C, D, E, f4, K10, expand (sha->key, 70u))( (E) += ( (((A)) << (5u)) | (((A)) >> (32-(5u))) ) + ( ((B)) ^ ((C)) ^ ((D)) ) + ((0xCA62C1D6u)) + ((sha-> key[(70u)&15u] = (t = sha->key[((70u))&15u] ^ sha-> key[(((70u))-14)&15u] ^ sha->key[(((70u))-8)&15u] ^ sha->key[(((70u))-3)&15u], ( ((t) << (1)) | ((t ) >> (32-(1))) )))), (B) = ( (((B)) << (30u)) | ( ((B)) >> (32-(30u))) ) ); | |||
1218 | subRound (E, A, B, C, D, f4, K10, expand (sha->key, 71u))( (D) += ( (((E)) << (5u)) | (((E)) >> (32-(5u))) ) + ( ((A)) ^ ((B)) ^ ((C)) ) + ((0xCA62C1D6u)) + ((sha-> key[(71u)&15u] = (t = sha->key[((71u))&15u] ^ sha-> key[(((71u))-14)&15u] ^ sha->key[(((71u))-8)&15u] ^ sha->key[(((71u))-3)&15u], ( ((t) << (1)) | ((t ) >> (32-(1))) )))), (A) = ( (((A)) << (30u)) | ( ((A)) >> (32-(30u))) ) ); | |||
1219 | subRound (D, E, A, B, C, f4, K10, expand (sha->key, 72u))( (C) += ( (((D)) << (5u)) | (((D)) >> (32-(5u))) ) + ( ((E)) ^ ((A)) ^ ((B)) ) + ((0xCA62C1D6u)) + ((sha-> key[(72u)&15u] = (t = sha->key[((72u))&15u] ^ sha-> key[(((72u))-14)&15u] ^ sha->key[(((72u))-8)&15u] ^ sha->key[(((72u))-3)&15u], ( ((t) << (1)) | ((t ) >> (32-(1))) )))), (E) = ( (((E)) << (30u)) | ( ((E)) >> (32-(30u))) ) ); | |||
1220 | subRound (C, D, E, A, B, f4, K10, expand (sha->key, 73u))( (B) += ( (((C)) << (5u)) | (((C)) >> (32-(5u))) ) + ( ((D)) ^ ((E)) ^ ((A)) ) + ((0xCA62C1D6u)) + ((sha-> key[(73u)&15u] = (t = sha->key[((73u))&15u] ^ sha-> key[(((73u))-14)&15u] ^ sha->key[(((73u))-8)&15u] ^ sha->key[(((73u))-3)&15u], ( ((t) << (1)) | ((t ) >> (32-(1))) )))), (D) = ( (((D)) << (30u)) | ( ((D)) >> (32-(30u))) ) ); | |||
1221 | subRound (B, C, D, E, A, f4, K10, expand (sha->key, 74u))( (A) += ( (((B)) << (5u)) | (((B)) >> (32-(5u))) ) + ( ((C)) ^ ((D)) ^ ((E)) ) + ((0xCA62C1D6u)) + ((sha-> key[(74u)&15u] = (t = sha->key[((74u))&15u] ^ sha-> key[(((74u))-14)&15u] ^ sha->key[(((74u))-8)&15u] ^ sha->key[(((74u))-3)&15u], ( ((t) << (1)) | ((t ) >> (32-(1))) )))), (C) = ( (((C)) << (30u)) | ( ((C)) >> (32-(30u))) ) ); | |||
1222 | subRound (A, B, C, D, E, f4, K10, expand (sha->key, 75u))( (E) += ( (((A)) << (5u)) | (((A)) >> (32-(5u))) ) + ( ((B)) ^ ((C)) ^ ((D)) ) + ((0xCA62C1D6u)) + ((sha-> key[(75u)&15u] = (t = sha->key[((75u))&15u] ^ sha-> key[(((75u))-14)&15u] ^ sha->key[(((75u))-8)&15u] ^ sha->key[(((75u))-3)&15u], ( ((t) << (1)) | ((t ) >> (32-(1))) )))), (B) = ( (((B)) << (30u)) | ( ((B)) >> (32-(30u))) ) ); | |||
1223 | subRound (E, A, B, C, D, f4, K10, expand (sha->key, 76u))( (D) += ( (((E)) << (5u)) | (((E)) >> (32-(5u))) ) + ( ((A)) ^ ((B)) ^ ((C)) ) + ((0xCA62C1D6u)) + ((sha-> key[(76u)&15u] = (t = sha->key[((76u))&15u] ^ sha-> key[(((76u))-14)&15u] ^ sha->key[(((76u))-8)&15u] ^ sha->key[(((76u))-3)&15u], ( ((t) << (1)) | ((t ) >> (32-(1))) )))), (A) = ( (((A)) << (30u)) | ( ((A)) >> (32-(30u))) ) ); | |||
1224 | subRound (D, E, A, B, C, f4, K10, expandx (sha->key, 77u))( (C) += ( (((D)) << (5u)) | (((D)) >> (32-(5u))) ) + ( ((E)) ^ ((A)) ^ ((B)) ) + ((0xCA62C1D6u)) + ((t = sha-> key[(77u)&15u] ^ sha->key[((77u)-14)&15u] ^ sha-> key[((77u)-8)&15u] ^ sha->key[((77u)-3)&15u], ( (( t) << (1)) | ((t) >> (32-(1))) ))), (E) = ( (((E) ) << (30u)) | (((E)) >> (32-(30u))) ) ); | |||
1225 | subRound (C, D, E, A, B, f4, K10, expandx (sha->key, 78u))( (B) += ( (((C)) << (5u)) | (((C)) >> (32-(5u))) ) + ( ((D)) ^ ((E)) ^ ((A)) ) + ((0xCA62C1D6u)) + ((t = sha-> key[(78u)&15u] ^ sha->key[((78u)-14)&15u] ^ sha-> key[((78u)-8)&15u] ^ sha->key[((78u)-3)&15u], ( (( t) << (1)) | ((t) >> (32-(1))) ))), (D) = ( (((D) ) << (30u)) | (((D)) >> (32-(30u))) ) ); | |||
1226 | subRound (B, C, D, E, A, f4, K10, expandx (sha->key, 79u))( (A) += ( (((B)) << (5u)) | (((B)) >> (32-(5u))) ) + ( ((C)) ^ ((D)) ^ ((E)) ) + ((0xCA62C1D6u)) + ((t = sha-> key[(79u)&15u] ^ sha->key[((79u)-14)&15u] ^ sha-> key[((79u)-8)&15u] ^ sha->key[((79u)-3)&15u], ( (( t) << (1)) | ((t) >> (32-(1))) ))), (C) = ( (((C) ) << (30u)) | (((C)) >> (32-(30u))) ) ); | |||
1227 | ||||
1228 | /* | |||
1229 | * Build message digest | |||
1230 | */ | |||
1231 | sha->iv[0] += A; | |||
1232 | sha->iv[1] += B; | |||
1233 | sha->iv[2] += C; | |||
1234 | sha->iv[3] += D; | |||
1235 | sha->iv[4] += E; | |||
1236 | } | |||
1237 | ||||
1238 | /* | |||
1239 | * Update SHA for a block of data. | |||
1240 | */ | |||
1241 | void Ns_CtxSHAUpdate(Ns_CtxSHA1 *ctx, const unsigned char *buf, size_t len) | |||
1242 | { | |||
1243 | unsigned i; | |||
1244 | ||||
1245 | NS_NONNULL_ASSERT(ctx != NULL)((void) (0)); | |||
1246 | NS_NONNULL_ASSERT(buf != NULL)((void) (0)); | |||
1247 | ||||
1248 | /* | |||
1249 | * Update bit count | |||
1250 | */ | |||
1251 | ||||
1252 | #if defined(HAVE_64BIT1) | |||
1253 | i = (unsigned) ctx->bytes % SHA_BLOCKBYTES64u; | |||
1254 | ctx->bytes += len; | |||
1255 | #else | |||
1256 | { | |||
1257 | uint32_t t = ctx->bytesLo; | |||
1258 | ctx->bytesLo = (uint32_t)(t + len); | |||
1259 | if (ctx->bytesLo < t) { | |||
1260 | ctx->bytesHi++; /* Carry from low to high */ | |||
1261 | } | |||
1262 | i = (unsigned) t % SHA_BLOCKBYTES64u; /* Bytes already in ctx->key */ | |||
1263 | } | |||
1264 | #endif | |||
1265 | ||||
1266 | /* | |||
1267 | * "i" is always less than SHA_BLOCKBYTES. | |||
1268 | */ | |||
1269 | if (SHA_BLOCKBYTES64u - i > len) { | |||
1270 | memcpy(ctx->key + i, buf, len); | |||
1271 | ||||
1272 | } else { | |||
1273 | if (i != 0u) { /* First chunk is an odd size */ | |||
1274 | memcpy(ctx->key + i, buf, SHA_BLOCKBYTES64u - i); | |||
1275 | SHAByteSwap(ctx->key, (const uint8_t *) ctx->key, SHA_BLOCKWORDS16U); | |||
1276 | SHATransform(ctx); | |||
1277 | buf += SHA_BLOCKBYTES64u - i; | |||
1278 | len -= SHA_BLOCKBYTES64u - i; | |||
1279 | } | |||
1280 | ||||
1281 | /* | |||
1282 | * Process data in 64-byte chunks | |||
1283 | */ | |||
1284 | while (len >= SHA_BLOCKBYTES64u) { | |||
1285 | SHAByteSwap(ctx->key, buf, SHA_BLOCKWORDS16U); | |||
1286 | SHATransform(ctx); | |||
1287 | buf += SHA_BLOCKBYTES64u; | |||
1288 | len -= SHA_BLOCKBYTES64u; | |||
1289 | } | |||
1290 | ||||
1291 | /* | |||
1292 | * Handle any remaining bytes of data. | |||
1293 | */ | |||
1294 | if (len != 0u) { | |||
1295 | memcpy(ctx->key, buf, len); | |||
1296 | } | |||
1297 | } | |||
1298 | } | |||
1299 | ||||
1300 | /* | |||
1301 | * Final wrap-up - pad to 64-byte boundary with the bit pattern | |||
1302 | * 1 0* (64-bit count of bits processed, MSB-first) | |||
1303 | */ | |||
1304 | void Ns_CtxSHAFinal(Ns_CtxSHA1 *ctx, unsigned char digest[20]) | |||
1305 | { | |||
1306 | #if defined(HAVE_64BIT1) | |||
1307 | unsigned i = (unsigned) ctx->bytes % SHA_BLOCKBYTES64u; | |||
1308 | #else | |||
1309 | unsigned i = (unsigned) ctx->bytesLo % SHA_BLOCKBYTES64u; | |||
1310 | #endif | |||
1311 | uint8_t *p = (uint8_t *) ctx->key + i; /* First unused byte */ | |||
1312 | ||||
1313 | /* | |||
1314 | * Set the first char of padding to 0x80. There is always room. | |||
1315 | */ | |||
1316 | *p++ = (uint8_t)0x80u; | |||
1317 | ||||
1318 | /* | |||
1319 | * Bytes of padding needed to make 64 bytes (0..63) | |||
1320 | */ | |||
1321 | i = (SHA_BLOCKBYTES64u - 1u) - i; | |||
1322 | ||||
1323 | if (i < 8u) { | |||
1324 | /* | |||
1325 | * Padding forces an extra block | |||
1326 | */ | |||
1327 | memset(p, 0, i); | |||
1328 | SHAByteSwap(ctx->key, (const uint8_t *) ctx->key, 16u); | |||
1329 | SHATransform(ctx); | |||
1330 | p = (uint8_t *) ctx->key; | |||
1331 | i = 64u; | |||
1332 | } | |||
1333 | memset(p, 0, i - 8u); | |||
1334 | SHAByteSwap(ctx->key, (const uint8_t *) ctx->key, 14u); | |||
1335 | ||||
1336 | /* | |||
1337 | * Append length in bits and transform | |||
1338 | */ | |||
1339 | #if defined(HAVE_64BIT1) | |||
1340 | ctx->key[14] = (uint32_t) (ctx->bytes >> 29); | |||
1341 | ctx->key[15] = (uint32_t) ctx->bytes << 3; | |||
1342 | #else | |||
1343 | ctx->key[14] = ctx->bytesHi << 3 | ctx->bytesLo >> 29; | |||
1344 | ctx->key[15] = ctx->bytesLo << 3; | |||
1345 | #endif | |||
1346 | SHATransform (ctx); | |||
1347 | ||||
1348 | /* | |||
1349 | * The following memcpy() does not seem to be correct and is most likely | |||
1350 | * not needed, since the loop sets all elements of "digetst". | |||
1351 | */ | |||
1352 | /*memcpy(digest, ctx->iv, sizeof(digest));*/ | |||
1353 | ||||
1354 | for (i = 0u; i < SHA_HASHWORDS5U; i++) { | |||
1355 | uint32_t t = ctx->iv[i]; | |||
1356 | ||||
1357 | digest[i * 4u ] = (uint8_t) (t >> 24); | |||
1358 | digest[i * 4u + 1u] = (uint8_t) (t >> 16); | |||
1359 | digest[i * 4u + 2u] = (uint8_t) (t >> 8); | |||
1360 | digest[i * 4u + 3u] = (uint8_t) t; | |||
1361 | } | |||
1362 | ||||
1363 | /* | |||
1364 | * In case it is sensitive | |||
1365 | */ | |||
1366 | memset(ctx, 0, sizeof(Ns_CtxSHA1)); | |||
1367 | } | |||
1368 | ||||
1369 | /* | |||
1370 | *---------------------------------------------------------------------- | |||
1371 | * | |||
1372 | * Ns_HexString -- | |||
1373 | * | |||
1374 | * Transform binary data to hex. The provided buffer must be | |||
1375 | * at least size*2 + 1 bytes long. | |||
1376 | * | |||
1377 | * Results: | |||
1378 | * buffer | |||
1379 | * | |||
1380 | * Side effects: | |||
1381 | * Updates passed-in buffer (2nd argument). | |||
1382 | * | |||
1383 | *---------------------------------------------------------------------- | |||
1384 | */ | |||
1385 | char * | |||
1386 | Ns_HexString(const unsigned char *octets, char *outputBuffer, int size, bool_Bool isUpper) | |||
1387 | { | |||
1388 | int i; | |||
1389 | static const char hexCharsUpper[] = "0123456789ABCDEF"; | |||
1390 | static const char hexCharsLower[] = "0123456789abcdef"; | |||
1391 | ||||
1392 | NS_NONNULL_ASSERT(octets != NULL)((void) (0)); | |||
1393 | NS_NONNULL_ASSERT(outputBuffer != NULL)((void) (0)); | |||
1394 | ||||
1395 | if (isUpper) { | |||
1396 | for (i = 0; i < size; ++i) { | |||
1397 | outputBuffer[i * 2] = hexCharsUpper[octets[i] >> 4]; | |||
1398 | outputBuffer[i * 2 + 1] = hexCharsUpper[octets[i] & 0xFu]; | |||
1399 | } | |||
1400 | } else { | |||
1401 | for (i = 0; i < size; ++i) { | |||
1402 | outputBuffer[i * 2] = hexCharsLower[octets[i] >> 4]; | |||
1403 | outputBuffer[i * 2 + 1] = hexCharsLower[octets[i] & 0xFu]; | |||
1404 | } | |||
1405 | } | |||
1406 | outputBuffer[size * 2] = '\0'; | |||
1407 | ||||
1408 | return outputBuffer; | |||
1409 | } | |||
1410 | ||||
1411 | ||||
1412 | /* | |||
1413 | *---------------------------------------------------------------------- | |||
1414 | * | |||
1415 | * NsTclSHA1ObjCmd -- | |||
1416 | * | |||
1417 | * Implements "ns_sha1". Returns a 40-character, hex-encoded string | |||
1418 | * containing the SHA1 hash of the first argument. | |||
1419 | * | |||
1420 | * Results: | |||
1421 | * NS_OK | |||
1422 | * | |||
1423 | * Side effects: | |||
1424 | * Tcl result is set to a string value. | |||
1425 | * | |||
1426 | *---------------------------------------------------------------------- | |||
1427 | */ | |||
1428 | ||||
1429 | int | |||
1430 | NsTclSHA1ObjCmd(ClientData UNUSED(clientData)UNUSED_clientData __attribute__((__unused__)), Tcl_Interp *interp, int objc, Tcl_Obj *const* objv) | |||
1431 | { | |||
1432 | int result = TCL_OK0, isBinary = 0; | |||
1433 | Tcl_Obj *charsObj; | |||
1434 | Ns_ObjvSpec opts[] = { | |||
1435 | {"-binary", Ns_ObjvBool, &isBinary, INT2PTR(NS_TRUE)((void *)(intptr_t)(1))}, | |||
1436 | {"--", Ns_ObjvBreak, NULL((void*)0), NULL((void*)0)}, | |||
1437 | {NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0)} | |||
1438 | }; | |||
1439 | Ns_ObjvSpec args[] = { | |||
1440 | {"string", Ns_ObjvObj, &charsObj, NULL((void*)0)}, | |||
1441 | {NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0)} | |||
1442 | }; | |||
1443 | ||||
1444 | if (Ns_ParseObjv(opts, args, interp, 1, objc, objv) != NS_OK) { | |||
1445 | result = TCL_ERROR1; | |||
1446 | ||||
1447 | } else { | |||
1448 | unsigned char digest[20]; | |||
1449 | char digestChars[41]; | |||
1450 | Ns_CtxSHA1 ctx; | |||
1451 | int nbytes; | |||
1452 | const unsigned char *bytes; | |||
1453 | Tcl_DString ds; | |||
1454 | ||||
1455 | Tcl_DStringInit(&ds); | |||
1456 | bytes = Ns_GetBinaryString(charsObj, isBinary == 1, &nbytes, &ds); | |||
1457 | //hexPrint("source ", bytes, (size_t)nbytes); | |||
1458 | ||||
1459 | Ns_CtxSHAInit(&ctx); | |||
1460 | Ns_CtxSHAUpdate(&ctx, bytes, (size_t) nbytes); | |||
1461 | Ns_CtxSHAFinal(&ctx, digest); | |||
1462 | ||||
1463 | Ns_HexString(digest, digestChars, 20, NS_TRUE1); | |||
1464 | Tcl_SetObjResult(interp, Tcl_NewStringObj(digestChars, 40)); | |||
1465 | Tcl_DStringFree(&ds); | |||
1466 | } | |||
1467 | ||||
1468 | return result; | |||
1469 | } | |||
1470 | ||||
1471 | ||||
1472 | /* | |||
1473 | *---------------------------------------------------------------------- | |||
1474 | * | |||
1475 | * NsTclFileStatObjCmd -- | |||
1476 | * | |||
1477 | * Implements "ns_filestat". Works as "file stat" command but uses native | |||
1478 | * call when Tcl VFS is not compiled. The reason for this when native | |||
1479 | * calls are used for speed, having still slow file stat does not help, | |||
1480 | * need to use native call and file stat is the most used command | |||
1481 | * | |||
1482 | * Results: | |||
1483 | * NS_OK | |||
1484 | * | |||
1485 | * Side effects: | |||
1486 | * Tcl result is set to a string value. | |||
1487 | * | |||
1488 | *---------------------------------------------------------------------- | |||
1489 | */ | |||
1490 | ||||
1491 | int | |||
1492 | NsTclFileStatObjCmd(ClientData UNUSED(clientData)UNUSED_clientData __attribute__((__unused__)), Tcl_Interp *interp, int objc, Tcl_Obj *const* objv) | |||
1493 | { | |||
1494 | int result = TCL_OK0; | |||
1495 | struct stat st; | |||
1496 | ||||
1497 | if (objc < 2) { | |||
1498 | Tcl_WrongNumArgs(interp, 1, objv, "file ?varname?"); | |||
1499 | result = TCL_ERROR1; | |||
1500 | } | |||
1501 | if (stat(Tcl_GetString(objv[1]), &st) != 0) { | |||
1502 | Tcl_SetObjResult(interp, Tcl_NewIntObj(0)); | |||
1503 | } else { | |||
1504 | if (objc > 2) { | |||
1505 | const char *name = Tcl_GetString(objv[2]); | |||
1506 | ||||
1507 | (void)Tcl_SetVar2Ex(interp, name, "dev", Tcl_NewWideIntObj((Tcl_WideInt)st.st_dev), 0); | |||
1508 | (void)Tcl_SetVar2Ex(interp, name, "ino", Tcl_NewWideIntObj((Tcl_WideInt)st.st_ino), 0); | |||
1509 | (void)Tcl_SetVar2Ex(interp, name, "nlink", Tcl_NewWideIntObj((Tcl_WideInt)st.st_nlink), 0); | |||
1510 | (void)Tcl_SetVar2Ex(interp, name, "uid", Tcl_NewWideIntObj((Tcl_WideInt)st.st_uid), 0); | |||
1511 | (void)Tcl_SetVar2Ex(interp, name, "gid", Tcl_NewWideIntObj((Tcl_WideInt)st.st_gid), 0); | |||
1512 | (void)Tcl_SetVar2Ex(interp, name, "size", Tcl_NewWideIntObj((Tcl_WideInt)st.st_size), 0); | |||
1513 | (void)Tcl_SetVar2Ex(interp, name, "atime", Tcl_NewWideIntObj((Tcl_WideInt)st.st_atimest_atim.tv_sec), 0); | |||
1514 | (void)Tcl_SetVar2Ex(interp, name, "ctime", Tcl_NewWideIntObj((Tcl_WideInt)st.st_ctimest_ctim.tv_sec), 0); | |||
1515 | (void)Tcl_SetVar2Ex(interp, name, "mtime", Tcl_NewWideIntObj((Tcl_WideInt)st.st_mtimest_mtim.tv_sec), 0); | |||
1516 | (void)Tcl_SetVar2Ex(interp, name, "mode", Tcl_NewWideIntObj((Tcl_WideInt)st.st_mode), 0); | |||
1517 | (void)Tcl_SetVar2Ex(interp, name, "type", Tcl_NewStringObj( | |||
1518 | (S_ISREG(st.st_mode)((((st.st_mode)) & 0170000) == (0100000)) ? "file" : | |||
1519 | S_ISDIR(st.st_mode)((((st.st_mode)) & 0170000) == (0040000)) ? "directory" : | |||
1520 | #ifdef S_ISCHR | |||
1521 | S_ISCHR(st.st_mode)((((st.st_mode)) & 0170000) == (0020000)) ? "characterSpecial" : | |||
1522 | #endif | |||
1523 | #ifdef S_ISBLK | |||
1524 | S_ISBLK(st.st_mode)((((st.st_mode)) & 0170000) == (0060000)) ? "blockSpecial" : | |||
1525 | #endif | |||
1526 | #ifdef S_ISFIFO | |||
1527 | S_ISFIFO(st.st_mode)((((st.st_mode)) & 0170000) == (0010000)) ? "fifo" : | |||
1528 | #endif | |||
1529 | #ifdef S_ISLNK | |||
1530 | S_ISLNK(st.st_mode)((((st.st_mode)) & 0170000) == (0120000)) ? "link" : | |||
1531 | #endif | |||
1532 | #ifdef S_ISSOCK | |||
1533 | S_ISSOCK(st.st_mode)((((st.st_mode)) & 0170000) == (0140000)) ? "socket" : | |||
1534 | #endif | |||
1535 | NS_EMPTY_STRING), -1), 0); | |||
1536 | } | |||
1537 | Tcl_SetObjResult(interp, Tcl_NewIntObj(1)); | |||
1538 | } | |||
1539 | return result; | |||
1540 | } | |||
1541 | ||||
1542 | /* | |||
1543 | * | |||
1544 | * This code implements the MD5 message-digest algorithm. | |||
1545 | * The algorithm is due to Ron Rivest. This code was | |||
1546 | * written by Colin Plumb in 1993, no copyright is claimed. | |||
1547 | * This code is in the public domain; do with it what you wish. | |||
1548 | * | |||
1549 | * Equivalent code is available from RSA Data Security, Inc. | |||
1550 | * This code has been tested against that, and is equivalent, | |||
1551 | * except that you don't need to include two pages of legalese | |||
1552 | * with every copy. | |||
1553 | * | |||
1554 | * To compute the message digest of a chunk of bytes, declare an | |||
1555 | * MD5Context structure, pass it to MD5Init, call MD5Update as | |||
1556 | * needed on buffers full of bytes, and then call MD5Final, which | |||
1557 | * will fill a supplied 16-byte array with the digest. | |||
1558 | */ | |||
1559 | ||||
1560 | #ifdef sun | |||
1561 | #define HIGHFIRST | |||
1562 | #endif | |||
1563 | ||||
1564 | #ifndef HIGHFIRST | |||
1565 | #define byteReverse(buf, len) /* Nothing */ | |||
1566 | #else | |||
1567 | /* | |||
1568 | * Note: this code is harmless on little-endian machines. | |||
1569 | */ | |||
1570 | static void byteReverse(unsigned char *buf, unsigned longs) | |||
1571 | { | |||
1572 | do { | |||
1573 | uint32_t t; | |||
1574 | ||||
1575 | t = (uint32_t) | |||
1576 | ((unsigned) buf[3] << 8 | buf[2]) << 16 | | |||
1577 | ((unsigned) buf[1] << 8 | buf[0]); | |||
1578 | *(uint32_t *) buf = t; | |||
1579 | buf += 4; | |||
1580 | } while (--longs); | |||
1581 | } | |||
1582 | #endif | |||
1583 | ||||
1584 | /* | |||
1585 | * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious | |||
1586 | * initialization constants. | |||
1587 | */ | |||
1588 | void Ns_CtxMD5Init(Ns_CtxMD5 *ctx) | |||
1589 | { | |||
1590 | ctx->buf[0] = 0x67452301u; | |||
1591 | ctx->buf[1] = 0xefcdab89u; | |||
1592 | ctx->buf[2] = 0x98badcfeU; | |||
1593 | ctx->buf[3] = 0x10325476u; | |||
1594 | ||||
1595 | ctx->bits[0] = 0u; | |||
1596 | ctx->bits[1] = 0u; | |||
1597 | } | |||
1598 | ||||
1599 | /* | |||
1600 | * Update context to reflect the concatenation of another buffer full | |||
1601 | * of bytes. | |||
1602 | */ | |||
1603 | void Ns_CtxMD5Update(Ns_CtxMD5 *ctx, const unsigned char *buf, size_t len) | |||
1604 | { | |||
1605 | uint32_t t; | |||
1606 | ||||
1607 | NS_NONNULL_ASSERT(ctx != NULL)((void) (0)); | |||
1608 | NS_NONNULL_ASSERT(buf != NULL)((void) (0)); | |||
1609 | ||||
1610 | /* | |||
1611 | * Update bit count. | |||
1612 | */ | |||
1613 | t = ctx->bits[0]; | |||
1614 | ctx->bits[0] = t + ((uint32_t) len << 3); | |||
1615 | if (ctx->bits[0] < t) { | |||
1616 | ctx->bits[1]++; /* Carry from low to high */ | |||
1617 | } | |||
1618 | ctx->bits[1] += (uint32_t)(len >> 29); | |||
1619 | ||||
1620 | t = (t >> 3) & 0x3Fu; /* Bytes already in shsInfo->data */ | |||
1621 | ||||
1622 | /* | |||
1623 | * Handle any leading odd-sized chunks | |||
1624 | */ | |||
1625 | ||||
1626 | if (t != 0u) { | |||
1627 | unsigned char *p = ctx->in + t; | |||
1628 | ||||
1629 | t = 64u - t; | |||
1630 | if (len < t) { | |||
1631 | memcpy(p, buf, len); | |||
1632 | return; | |||
1633 | } | |||
1634 | memcpy(p, buf, t); | |||
1635 | byteReverse(ctx->in, 16); | |||
1636 | MD5Transform(ctx->buf, (uint32_t *) ctx->in); | |||
1637 | buf += t; | |||
1638 | len -= t; | |||
1639 | } | |||
1640 | ||||
1641 | /* | |||
1642 | * Process data in 64-byte chunks | |||
1643 | */ | |||
1644 | while (len >= 64u) { | |||
1645 | memcpy(ctx->in, buf, 64u); | |||
1646 | byteReverse(ctx->in, 16); | |||
1647 | MD5Transform(ctx->buf, (uint32_t *) ctx->in); | |||
1648 | buf += 64; | |||
1649 | len -= 64u; | |||
1650 | } | |||
1651 | ||||
1652 | /* | |||
1653 | * Handle any remaining bytes of data. | |||
1654 | */ | |||
1655 | memcpy(ctx->in, buf, len); | |||
1656 | } | |||
1657 | ||||
1658 | /* | |||
1659 | * Final wrap-up - pad to 64-byte boundary with the bit pattern | |||
1660 | * 1 0* (64-bit count of bits processed, MSB-first) | |||
1661 | */ | |||
1662 | void Ns_CtxMD5Final(Ns_CtxMD5 *ctx, unsigned char digest[16]) | |||
1663 | { | |||
1664 | unsigned count; | |||
1665 | uint8_t *p; | |||
1666 | uint32_t *words; | |||
1667 | ||||
1668 | NS_NONNULL_ASSERT(ctx != NULL)((void) (0)); | |||
1669 | NS_NONNULL_ASSERT(digest != NULL)((void) (0)); | |||
1670 | ||||
1671 | words = (uint32_t *)ctx->in; | |||
1672 | ||||
1673 | /* | |||
1674 | * Compute number of bytes mod 64 | |||
1675 | */ | |||
1676 | count = (ctx->bits[0] >> 3) & 0x3Fu; | |||
1677 | ||||
1678 | /* | |||
1679 | * Set the first char of padding to 0x80. This is safe since there is | |||
1680 | * always at least one byte free | |||
1681 | */ | |||
1682 | p = ctx->in + count; | |||
1683 | *p++ = (uint8_t)0x80u; | |||
1684 | ||||
1685 | /* | |||
1686 | * Bytes of padding needed to make 64 bytes | |||
1687 | */ | |||
1688 | count = (64u - 1u) - count; | |||
1689 | ||||
1690 | /* | |||
1691 | * Pad out to 56 mod 64 | |||
1692 | */ | |||
1693 | if (count < 8u) { | |||
1694 | /* | |||
1695 | * Two lots of padding: Pad the first block to 64 bytes | |||
1696 | */ | |||
1697 | memset(p, 0, count); | |||
1698 | byteReverse(ctx->in, 16); | |||
1699 | MD5Transform(ctx->buf, (uint32_t *) ctx->in); | |||
1700 | ||||
1701 | /* | |||
1702 | * Now fill the next block with 56 bytes | |||
1703 | */ | |||
1704 | memset(ctx->in, 0, 56u); | |||
1705 | } else { | |||
1706 | /* | |||
1707 | * Pad block to 56 bytes | |||
1708 | */ | |||
1709 | memset(p, 0, count - 8u); | |||
1710 | } | |||
1711 | byteReverse(ctx->in, 14); | |||
1712 | ||||
1713 | /* | |||
1714 | * Append length in bits and transform | |||
1715 | */ | |||
1716 | words[14] = ctx->bits[0]; | |||
1717 | words[15] = ctx->bits[1]; | |||
1718 | ||||
1719 | MD5Transform(ctx->buf, (uint32_t *) ctx->in); | |||
1720 | byteReverse((unsigned char *) ctx->buf, 4); | |||
1721 | memcpy(digest, ctx->buf, 16u); | |||
1722 | /* | |||
1723 | * This memset should not be needed, since this is performed at the end of | |||
1724 | * the operation. In case, it would be needed, it should be necessary at | |||
1725 | * the initialization of the structure. | |||
1726 | * | |||
1727 | * memset(ctx, 0, sizeof(Ns_CtxMD5)); | |||
1728 | */ | |||
1729 | } | |||
1730 | ||||
1731 | /* | |||
1732 | * The four core functions - F1 is optimized somewhat | |||
1733 | */ | |||
1734 | ||||
1735 | /* #define F1(x, y, z) (x & y | ~x & z) */ | |||
1736 | #define F1(x, y, z)((z) ^ ((x) & ((y) ^ (z)))) ((z) ^ ((x) & ((y) ^ (z)))) | |||
1737 | #define F2(x, y, z)((((y)) ^ (((z)) & (((x)) ^ ((y)))))) (F1((z), (x), (y))(((y)) ^ (((z)) & (((x)) ^ ((y)))))) | |||
1738 | #define F3(x, y, z)((x) ^ (y) ^ (z)) ((x) ^ (y) ^ (z)) | |||
1739 | #define F4(x, y, z)((y) ^ ((x) | ~(z))) ((y) ^ ((x) | ~(z))) | |||
1740 | ||||
1741 | /* | |||
1742 | * This is the central step in the MD5 algorithm. | |||
1743 | */ | |||
1744 | #define MD5STEP(f, w, x, y, z, data, s)( (w) += f((x), (y), (z)) + (data), (w) = (w)<<(s) | (w )>>(32-(s)), (w) += (x) ) \ | |||
1745 | ( (w) += f((x), (y), (z)) + (data), (w) = (w)<<(s) | (w)>>(32-(s)), (w) += (x) ) | |||
1746 | ||||
1747 | /* | |||
1748 | * The core of the MD5 algorithm, this alters an existing MD5 hash to reflect | |||
1749 | * the addition of 16 32-bit words (64 bytes) of new data. MD5Update blocks the | |||
1750 | * data and converts bytes into longwords for this routine. | |||
1751 | */ | |||
1752 | static void MD5Transform(uint32_t buf[4], const uint32_t block[16]) | |||
1753 | { | |||
1754 | register uint32_t a, b, c, d; | |||
1755 | ||||
1756 | #ifndef HIGHFIRST | |||
1757 | const uint32_t *in = block; | |||
1758 | #else | |||
1759 | uint32_t in[16]; | |||
1760 | ||||
1761 | memcpy(in, block, sizeof(in)); | |||
1762 | ||||
1763 | for (a = 0; a < 16; a++) { | |||
1764 | in[a] = (uint32_t)( | |||
1765 | (uint32_t)(block[a * 4 + 0]) | | |||
1766 | (uint32_t)(block[a * 4 + 1]) << 8 | | |||
1767 | (uint32_t)(block[a * 4 + 2]) << 16 | | |||
1768 | (uint32_t)(block[a * 4 + 3]) << 24); | |||
1769 | } | |||
1770 | #endif | |||
1771 | ||||
1772 | NS_NONNULL_ASSERT(buf != NULL)((void) (0)); | |||
1773 | NS_NONNULL_ASSERT(block != NULL)((void) (0)); | |||
1774 | ||||
1775 | a = buf[0]; | |||
1776 | b = buf[1]; | |||
1777 | c = buf[2]; | |||
1778 | d = buf[3]; | |||
1779 | ||||
1780 | MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478u, 7)( (a) += (((d)) ^ (((b)) & (((c)) ^ ((d))))) + (in[0] + 0xd76aa478u ), (a) = (a)<<(7) | (a)>>(32-(7)), (a) += (b) ); | |||
1781 | MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756u, 12)( (d) += (((c)) ^ (((a)) & (((b)) ^ ((c))))) + (in[1] + 0xe8c7b756u ), (d) = (d)<<(12) | (d)>>(32-(12)), (d) += (a) ); | |||
1782 | MD5STEP(F1, c, d, a, b, in[2] + 0x242070dbU, 17)( (c) += (((b)) ^ (((d)) & (((a)) ^ ((b))))) + (in[2] + 0x242070dbU ), (c) = (c)<<(17) | (c)>>(32-(17)), (c) += (d) ); | |||
1783 | MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceeeU, 22)( (b) += (((a)) ^ (((c)) & (((d)) ^ ((a))))) + (in[3] + 0xc1bdceeeU ), (b) = (b)<<(22) | (b)>>(32-(22)), (b) += (c) ); | |||
1784 | MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0fafU, 7)( (a) += (((d)) ^ (((b)) & (((c)) ^ ((d))))) + (in[4] + 0xf57c0fafU ), (a) = (a)<<(7) | (a)>>(32-(7)), (a) += (b) ); | |||
1785 | MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62aU, 12)( (d) += (((c)) ^ (((a)) & (((b)) ^ ((c))))) + (in[5] + 0x4787c62aU ), (d) = (d)<<(12) | (d)>>(32-(12)), (d) += (a) ); | |||
1786 | MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613u, 17)( (c) += (((b)) ^ (((d)) & (((a)) ^ ((b))))) + (in[6] + 0xa8304613u ), (c) = (c)<<(17) | (c)>>(32-(17)), (c) += (d) ); | |||
1787 | MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501u, 22)( (b) += (((a)) ^ (((c)) & (((d)) ^ ((a))))) + (in[7] + 0xfd469501u ), (b) = (b)<<(22) | (b)>>(32-(22)), (b) += (c) ); | |||
1788 | MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8u, 7)( (a) += (((d)) ^ (((b)) & (((c)) ^ ((d))))) + (in[8] + 0x698098d8u ), (a) = (a)<<(7) | (a)>>(32-(7)), (a) += (b) ); | |||
1789 | MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7afU, 12)( (d) += (((c)) ^ (((a)) & (((b)) ^ ((c))))) + (in[9] + 0x8b44f7afU ), (d) = (d)<<(12) | (d)>>(32-(12)), (d) += (a) ); | |||
1790 | MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1u, 17)( (c) += (((b)) ^ (((d)) & (((a)) ^ ((b))))) + (in[10] + 0xffff5bb1u ), (c) = (c)<<(17) | (c)>>(32-(17)), (c) += (d) ); | |||
1791 | MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7beU, 22)( (b) += (((a)) ^ (((c)) & (((d)) ^ ((a))))) + (in[11] + 0x895cd7beU ), (b) = (b)<<(22) | (b)>>(32-(22)), (b) += (c) ); | |||
1792 | MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122u, 7)( (a) += (((d)) ^ (((b)) & (((c)) ^ ((d))))) + (in[12] + 0x6b901122u ), (a) = (a)<<(7) | (a)>>(32-(7)), (a) += (b) ); | |||
1793 | MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193u, 12)( (d) += (((c)) ^ (((a)) & (((b)) ^ ((c))))) + (in[13] + 0xfd987193u ), (d) = (d)<<(12) | (d)>>(32-(12)), (d) += (a) ); | |||
1794 | MD5STEP(F1, c, d, a, b, in[14] + 0xa679438eU, 17)( (c) += (((b)) ^ (((d)) & (((a)) ^ ((b))))) + (in[14] + 0xa679438eU ), (c) = (c)<<(17) | (c)>>(32-(17)), (c) += (d) ); | |||
1795 | MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821u, 22)( (b) += (((a)) ^ (((c)) & (((d)) ^ ((a))))) + (in[15] + 0x49b40821u ), (b) = (b)<<(22) | (b)>>(32-(22)), (b) += (c) ); | |||
1796 | ||||
1797 | MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562u, 5)( (a) += (((((c))) ^ ((((d))) & ((((b))) ^ (((c))))))) + ( in[1] + 0xf61e2562u), (a) = (a)<<(5) | (a)>>(32-( 5)), (a) += (b) ); | |||
1798 | MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340u, 9)( (d) += (((((b))) ^ ((((c))) & ((((a))) ^ (((b))))))) + ( in[6] + 0xc040b340u), (d) = (d)<<(9) | (d)>>(32-( 9)), (d) += (a) ); | |||
1799 | MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51u, 14)( (c) += (((((a))) ^ ((((b))) & ((((d))) ^ (((a))))))) + ( in[11] + 0x265e5a51u), (c) = (c)<<(14) | (c)>>(32 -(14)), (c) += (d) ); | |||
1800 | MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aaU, 20)( (b) += (((((d))) ^ ((((a))) & ((((c))) ^ (((d))))))) + ( in[0] + 0xe9b6c7aaU), (b) = (b)<<(20) | (b)>>(32- (20)), (b) += (c) ); | |||
1801 | MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105dU, 5)( (a) += (((((c))) ^ ((((d))) & ((((b))) ^ (((c))))))) + ( in[5] + 0xd62f105dU), (a) = (a)<<(5) | (a)>>(32-( 5)), (a) += (b) ); | |||
1802 | MD5STEP(F2, d, a, b, c, in[10] + 0x02441453u, 9)( (d) += (((((b))) ^ ((((c))) & ((((a))) ^ (((b))))))) + ( in[10] + 0x02441453u), (d) = (d)<<(9) | (d)>>(32- (9)), (d) += (a) ); | |||
1803 | MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681u, 14)( (c) += (((((a))) ^ ((((b))) & ((((d))) ^ (((a))))))) + ( in[15] + 0xd8a1e681u), (c) = (c)<<(14) | (c)>>(32 -(14)), (c) += (d) ); | |||
1804 | MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8u, 20)( (b) += (((((d))) ^ ((((a))) & ((((c))) ^ (((d))))))) + ( in[4] + 0xe7d3fbc8u), (b) = (b)<<(20) | (b)>>(32- (20)), (b) += (c) ); | |||
1805 | MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6u, 5)( (a) += (((((c))) ^ ((((d))) & ((((b))) ^ (((c))))))) + ( in[9] + 0x21e1cde6u), (a) = (a)<<(5) | (a)>>(32-( 5)), (a) += (b) ); | |||
1806 | MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6u, 9)( (d) += (((((b))) ^ ((((c))) & ((((a))) ^ (((b))))))) + ( in[14] + 0xc33707d6u), (d) = (d)<<(9) | (d)>>(32- (9)), (d) += (a) ); | |||
1807 | MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87u, 14)( (c) += (((((a))) ^ ((((b))) & ((((d))) ^ (((a))))))) + ( in[3] + 0xf4d50d87u), (c) = (c)<<(14) | (c)>>(32- (14)), (c) += (d) ); | |||
1808 | MD5STEP(F2, b, c, d, a, in[8] + 0x455a14edU, 20)( (b) += (((((d))) ^ ((((a))) & ((((c))) ^ (((d))))))) + ( in[8] + 0x455a14edU), (b) = (b)<<(20) | (b)>>(32- (20)), (b) += (c) ); | |||
1809 | MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905u, 5)( (a) += (((((c))) ^ ((((d))) & ((((b))) ^ (((c))))))) + ( in[13] + 0xa9e3e905u), (a) = (a)<<(5) | (a)>>(32- (5)), (a) += (b) ); | |||
1810 | MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8u, 9)( (d) += (((((b))) ^ ((((c))) & ((((a))) ^ (((b))))))) + ( in[2] + 0xfcefa3f8u), (d) = (d)<<(9) | (d)>>(32-( 9)), (d) += (a) ); | |||
1811 | MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9u, 14)( (c) += (((((a))) ^ ((((b))) & ((((d))) ^ (((a))))))) + ( in[7] + 0x676f02d9u), (c) = (c)<<(14) | (c)>>(32- (14)), (c) += (d) ); | |||
1812 | MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8aU, 20)( (b) += (((((d))) ^ ((((a))) & ((((c))) ^ (((d))))))) + ( in[12] + 0x8d2a4c8aU), (b) = (b)<<(20) | (b)>>(32 -(20)), (b) += (c) ); | |||
1813 | ||||
1814 | MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942u, 4)( (a) += (((b)) ^ ((c)) ^ ((d))) + (in[5] + 0xfffa3942u), (a) = (a)<<(4) | (a)>>(32-(4)), (a) += (b) ); | |||
1815 | MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681u, 11)( (d) += (((a)) ^ ((b)) ^ ((c))) + (in[8] + 0x8771f681u), (d) = (d)<<(11) | (d)>>(32-(11)), (d) += (a) ); | |||
1816 | MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122u, 16)( (c) += (((d)) ^ ((a)) ^ ((b))) + (in[11] + 0x6d9d6122u), (c ) = (c)<<(16) | (c)>>(32-(16)), (c) += (d) ); | |||
1817 | MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380cU, 23)( (b) += (((c)) ^ ((d)) ^ ((a))) + (in[14] + 0xfde5380cU), (b ) = (b)<<(23) | (b)>>(32-(23)), (b) += (c) ); | |||
1818 | MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44u, 4)( (a) += (((b)) ^ ((c)) ^ ((d))) + (in[1] + 0xa4beea44u), (a) = (a)<<(4) | (a)>>(32-(4)), (a) += (b) ); | |||
1819 | MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9u, 11)( (d) += (((a)) ^ ((b)) ^ ((c))) + (in[4] + 0x4bdecfa9u), (d) = (d)<<(11) | (d)>>(32-(11)), (d) += (a) ); | |||
1820 | MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60u, 16)( (c) += (((d)) ^ ((a)) ^ ((b))) + (in[7] + 0xf6bb4b60u), (c) = (c)<<(16) | (c)>>(32-(16)), (c) += (d) ); | |||
1821 | MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70u, 23)( (b) += (((c)) ^ ((d)) ^ ((a))) + (in[10] + 0xbebfbc70u), (b ) = (b)<<(23) | (b)>>(32-(23)), (b) += (c) ); | |||
1822 | MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6u, 4)( (a) += (((b)) ^ ((c)) ^ ((d))) + (in[13] + 0x289b7ec6u), (a ) = (a)<<(4) | (a)>>(32-(4)), (a) += (b) ); | |||
1823 | MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127faU, 11)( (d) += (((a)) ^ ((b)) ^ ((c))) + (in[0] + 0xeaa127faU), (d) = (d)<<(11) | (d)>>(32-(11)), (d) += (a) ); | |||
1824 | MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085u, 16)( (c) += (((d)) ^ ((a)) ^ ((b))) + (in[3] + 0xd4ef3085u), (c) = (c)<<(16) | (c)>>(32-(16)), (c) += (d) ); | |||
1825 | MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05u, 23)( (b) += (((c)) ^ ((d)) ^ ((a))) + (in[6] + 0x04881d05u), (b) = (b)<<(23) | (b)>>(32-(23)), (b) += (c) ); | |||
1826 | MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039u, 4)( (a) += (((b)) ^ ((c)) ^ ((d))) + (in[9] + 0xd9d4d039u), (a) = (a)<<(4) | (a)>>(32-(4)), (a) += (b) ); | |||
1827 | MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5u, 11)( (d) += (((a)) ^ ((b)) ^ ((c))) + (in[12] + 0xe6db99e5u), (d ) = (d)<<(11) | (d)>>(32-(11)), (d) += (a) ); | |||
1828 | MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8u, 16)( (c) += (((d)) ^ ((a)) ^ ((b))) + (in[15] + 0x1fa27cf8u), (c ) = (c)<<(16) | (c)>>(32-(16)), (c) += (d) ); | |||
1829 | MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665u, 23)( (b) += (((c)) ^ ((d)) ^ ((a))) + (in[2] + 0xc4ac5665u), (b) = (b)<<(23) | (b)>>(32-(23)), (b) += (c) ); | |||
1830 | ||||
1831 | MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244u, 6)( (a) += (((c)) ^ (((b)) | ~((d)))) + (in[0] + 0xf4292244u), ( a) = (a)<<(6) | (a)>>(32-(6)), (a) += (b) ); | |||
1832 | MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97u, 10)( (d) += (((b)) ^ (((a)) | ~((c)))) + (in[7] + 0x432aff97u), ( d) = (d)<<(10) | (d)>>(32-(10)), (d) += (a) ); | |||
1833 | MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7u, 15)( (c) += (((a)) ^ (((d)) | ~((b)))) + (in[14] + 0xab9423a7u), (c) = (c)<<(15) | (c)>>(32-(15)), (c) += (d) ); | |||
1834 | MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039u, 21)( (b) += (((d)) ^ (((c)) | ~((a)))) + (in[5] + 0xfc93a039u), ( b) = (b)<<(21) | (b)>>(32-(21)), (b) += (c) ); | |||
1835 | MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3u, 6)( (a) += (((c)) ^ (((b)) | ~((d)))) + (in[12] + 0x655b59c3u), (a) = (a)<<(6) | (a)>>(32-(6)), (a) += (b) ); | |||
1836 | MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92u, 10)( (d) += (((b)) ^ (((a)) | ~((c)))) + (in[3] + 0x8f0ccc92u), ( d) = (d)<<(10) | (d)>>(32-(10)), (d) += (a) ); | |||
1837 | MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47dU, 15)( (c) += (((a)) ^ (((d)) | ~((b)))) + (in[10] + 0xffeff47dU), (c) = (c)<<(15) | (c)>>(32-(15)), (c) += (d) ); | |||
1838 | MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1u, 21)( (b) += (((d)) ^ (((c)) | ~((a)))) + (in[1] + 0x85845dd1u), ( b) = (b)<<(21) | (b)>>(32-(21)), (b) += (c) ); | |||
1839 | MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4fU, 6)( (a) += (((c)) ^ (((b)) | ~((d)))) + (in[8] + 0x6fa87e4fU), ( a) = (a)<<(6) | (a)>>(32-(6)), (a) += (b) ); | |||
1840 | MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0u, 10)( (d) += (((b)) ^ (((a)) | ~((c)))) + (in[15] + 0xfe2ce6e0u), (d) = (d)<<(10) | (d)>>(32-(10)), (d) += (a) ); | |||
1841 | MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314u, 15)( (c) += (((a)) ^ (((d)) | ~((b)))) + (in[6] + 0xa3014314u), ( c) = (c)<<(15) | (c)>>(32-(15)), (c) += (d) ); | |||
1842 | MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1u, 21)( (b) += (((d)) ^ (((c)) | ~((a)))) + (in[13] + 0x4e0811a1u), (b) = (b)<<(21) | (b)>>(32-(21)), (b) += (c) ); | |||
1843 | MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82u, 6)( (a) += (((c)) ^ (((b)) | ~((d)))) + (in[4] + 0xf7537e82u), ( a) = (a)<<(6) | (a)>>(32-(6)), (a) += (b) ); | |||
1844 | MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235u, 10)( (d) += (((b)) ^ (((a)) | ~((c)))) + (in[11] + 0xbd3af235u), (d) = (d)<<(10) | (d)>>(32-(10)), (d) += (a) ); | |||
1845 | MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bbU, 15)( (c) += (((a)) ^ (((d)) | ~((b)))) + (in[2] + 0x2ad7d2bbU), ( c) = (c)<<(15) | (c)>>(32-(15)), (c) += (d) ); | |||
1846 | MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391u, 21)( (b) += (((d)) ^ (((c)) | ~((a)))) + (in[9] + 0xeb86d391u), ( b) = (b)<<(21) | (b)>>(32-(21)), (b) += (c) ); | |||
1847 | ||||
1848 | buf[0] += a; | |||
1849 | buf[1] += b; | |||
1850 | buf[2] += c; | |||
1851 | buf[3] += d; | |||
1852 | } | |||
1853 | ||||
1854 | /* | |||
1855 | *---------------------------------------------------------------------- | |||
1856 | * | |||
1857 | * NsTclMD5ObjCmd -- | |||
1858 | * | |||
1859 | * Implements "ns_md5". Returns a 32-character, hex-encoded string | |||
1860 | * containing the MD5 hash of the first argument. | |||
1861 | * | |||
1862 | * Results: | |||
1863 | * NS_OK | |||
1864 | * | |||
1865 | * Side effects: | |||
1866 | * Tcl result is set to a string value. | |||
1867 | * | |||
1868 | *---------------------------------------------------------------------- | |||
1869 | */ | |||
1870 | ||||
1871 | int | |||
1872 | NsTclMD5ObjCmd(ClientData UNUSED(clientData)UNUSED_clientData __attribute__((__unused__)), Tcl_Interp *interp, int objc, Tcl_Obj *const* objv) | |||
1873 | { | |||
1874 | int result = TCL_OK0, isBinary = 0; | |||
1875 | Tcl_Obj *charsObj; | |||
1876 | Ns_ObjvSpec opts[] = { | |||
1877 | {"-binary", Ns_ObjvBool, &isBinary, INT2PTR(NS_TRUE)((void *)(intptr_t)(1))}, | |||
1878 | {"--", Ns_ObjvBreak, NULL((void*)0), NULL((void*)0)}, | |||
1879 | {NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0)} | |||
1880 | }; | |||
1881 | Ns_ObjvSpec args[] = { | |||
1882 | {"string", Ns_ObjvObj, &charsObj, NULL((void*)0)}, | |||
1883 | {NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0)} | |||
1884 | }; | |||
1885 | ||||
1886 | if (Ns_ParseObjv(opts, args, interp, 1, objc, objv) != NS_OK) { | |||
1887 | result = TCL_ERROR1; | |||
1888 | ||||
1889 | } else { | |||
1890 | Ns_CtxMD5 ctx; | |||
1891 | unsigned char digest[16]; | |||
1892 | char digestChars[33]; | |||
1893 | int length; | |||
1894 | Tcl_DString ds; | |||
1895 | const unsigned char *str; | |||
1896 | ||||
1897 | Tcl_DStringInit(&ds); | |||
1898 | str = Ns_GetBinaryString(charsObj, isBinary == 1, &length, &ds); | |||
1899 | Ns_CtxMD5Init(&ctx); | |||
1900 | Ns_CtxMD5Update(&ctx, (const unsigned char *) str, (size_t)length); | |||
1901 | Ns_CtxMD5Final(&ctx, digest); | |||
1902 | ||||
1903 | Ns_HexString(digest, digestChars, 16, NS_TRUE1); | |||
1904 | Tcl_SetObjResult(interp, Tcl_NewStringObj(digestChars, 32)); | |||
1905 | Tcl_DStringFree(&ds); | |||
1906 | } | |||
1907 | ||||
1908 | return result; | |||
1909 | } | |||
1910 | ||||
1911 | /* | |||
1912 | *---------------------------------------------------------------------- | |||
1913 | * | |||
1914 | * NsTclSetUserObjCmd, NsTclSetGroupObjCmd -- | |||
1915 | * | |||
1916 | * Implements "ns_setuser" and "ns_setgroup". | |||
1917 | * | |||
1918 | * Results: | |||
1919 | * Standard Tcl result code. | |||
1920 | * | |||
1921 | * Side effects: | |||
1922 | * Error message will be output in the log file, not returned as Tcl result | |||
1923 | * | |||
1924 | *---------------------------------------------------------------------- | |||
1925 | */ | |||
1926 | ||||
1927 | int | |||
1928 | NsTclSetUserObjCmd(ClientData UNUSED(clientData)UNUSED_clientData __attribute__((__unused__)), Tcl_Interp *interp, | |||
1929 | int objc, Tcl_Obj *const* objv) | |||
1930 | { | |||
1931 | int result = TCL_OK0; | |||
1932 | ||||
1933 | if (objc < 2) { | |||
1934 | Tcl_WrongNumArgs(interp, 1, objv, "user"); | |||
1935 | result = TCL_ERROR1; | |||
1936 | ||||
1937 | } else { | |||
1938 | Tcl_SetObjResult(interp, Tcl_NewIntObj(Ns_SetUser(Tcl_GetString(objv[1])))); | |||
1939 | } | |||
1940 | ||||
1941 | return result; | |||
1942 | } | |||
1943 | ||||
1944 | int | |||
1945 | NsTclSetGroupObjCmd(ClientData UNUSED(clientData)UNUSED_clientData __attribute__((__unused__)), Tcl_Interp *interp, | |||
1946 | int objc, Tcl_Obj *const* objv) | |||
1947 | { | |||
1948 | int result = TCL_OK0; | |||
1949 | ||||
1950 | if (objc < 2) { | |||
1951 | Tcl_WrongNumArgs(interp, 1, objv, "group"); | |||
1952 | result = TCL_ERROR1; | |||
1953 | ||||
1954 | } else { | |||
1955 | Tcl_SetObjResult(interp, Tcl_NewIntObj(Ns_SetGroup(Tcl_GetString(objv[1])))); | |||
1956 | } | |||
1957 | return result; | |||
1958 | } | |||
1959 | ||||
1960 | #ifndef _WIN32 | |||
1961 | ||||
1962 | /* | |||
1963 | *---------------------------------------------------------------------- | |||
1964 | * | |||
1965 | * GetLimitObj -- | |||
1966 | * | |||
1967 | * Get single resource limit in form of a Tcl_Obj | |||
1968 | * | |||
1969 | * Results: | |||
1970 | * Tcl_Obj | |||
1971 | * | |||
1972 | * Side effects: | |||
1973 | * None. | |||
1974 | * | |||
1975 | *---------------------------------------------------------------------- | |||
1976 | */ | |||
1977 | static Tcl_Obj * | |||
1978 | GetLimitObj(rlim_t value) | |||
1979 | { | |||
1980 | Tcl_Obj *obj; | |||
1981 | ||||
1982 | if (value == RLIM_INFINITY((__rlim_t) -1)) { | |||
1983 | obj = Tcl_NewStringObj("unlimited", -1); | |||
1984 | } else { | |||
1985 | obj = Tcl_NewWideIntObj((Tcl_WideInt)value); | |||
1986 | } | |||
1987 | return obj; | |||
1988 | } | |||
1989 | #endif | |||
1990 | ||||
1991 | ||||
1992 | /* | |||
1993 | *---------------------------------------------------------------------- | |||
1994 | * | |||
1995 | * NsTclRlimitObjCmd -- | |||
1996 | * | |||
1997 | * Implements "ns_rlimit". Get or set a resource limit in the operating | |||
1998 | * system. | |||
1999 | * | |||
2000 | * Results: | |||
2001 | * Pair of actual value and maximum value | |||
2002 | * | |||
2003 | * Side effects: | |||
2004 | * Change resource limit with called with a value. | |||
2005 | * | |||
2006 | *---------------------------------------------------------------------- | |||
2007 | */ | |||
2008 | int | |||
2009 | NsTclRlimitObjCmd(ClientData UNUSED(clientData)UNUSED_clientData __attribute__((__unused__)), Tcl_Interp *interp, int objc, Tcl_Obj *const* objv) | |||
2010 | { | |||
2011 | #ifndef _WIN32 | |||
2012 | # ifndef RLIMIT_ASRLIMIT_AS | |||
2013 | # define RLIMIT_ASRLIMIT_AS RLIMIT_DATARLIMIT_DATA | |||
2014 | # endif | |||
2015 | ||||
2016 | int opt, result = TCL_OK0, rc; | |||
2017 | struct rlimit rlimit; | |||
2018 | ||||
2019 | static const char *const opts[] = { | |||
2020 | "coresize", | |||
2021 | "datasize", | |||
2022 | "files", | |||
2023 | "filesize", | |||
2024 | "vmsize", | |||
2025 | NULL((void*)0) | |||
2026 | }; | |||
2027 | static int resource[] = { | |||
2028 | RLIMIT_CORERLIMIT_CORE, | |||
2029 | RLIMIT_DATARLIMIT_DATA, | |||
2030 | RLIMIT_NOFILERLIMIT_NOFILE, | |||
2031 | RLIMIT_FSIZERLIMIT_FSIZE, | |||
2032 | RLIMIT_ASRLIMIT_AS | |||
2033 | }; | |||
2034 | enum { | |||
2035 | CCoresizeIdx, | |||
2036 | CDatasizeIdx, | |||
2037 | CFIlesizeIdx, | |||
2038 | CFilesIdx, | |||
2039 | CVmsizeIdx, | |||
2040 | ||||
2041 | }; | |||
2042 | ||||
2043 | if (objc < 2) { | |||
2044 | Tcl_WrongNumArgs(interp, 1, objv, "command ?args?"); | |||
2045 | return TCL_ERROR1; | |||
2046 | } | |||
2047 | if (Tcl_GetIndexFromObj(interp, objv[1], opts,Tcl_GetIndexFromObjStruct(interp, objv[1], opts, sizeof(char * ), "option", 0, &opt) | |||
2048 | "option", 0, &opt)Tcl_GetIndexFromObjStruct(interp, objv[1], opts, sizeof(char * ), "option", 0, &opt) != TCL_OK0) { | |||
2049 | return TCL_ERROR1; | |||
2050 | } | |||
2051 | ||||
2052 | if (objc == 2) { | |||
2053 | rc = getrlimit(resource[opt], &rlimit); | |||
2054 | if (rc == -1) { | |||
2055 | Ns_TclPrintfResult(interp, "getrlimit returned error"); | |||
2056 | result = TCL_ERROR1; | |||
2057 | } | |||
2058 | } else if (objc == 3) { | |||
2059 | Tcl_WideInt value; | |||
2060 | ||||
2061 | result = Tcl_GetWideIntFromObj(interp, objv[2], &value); | |||
2062 | if (result != TCL_OK0) { | |||
2063 | char *valueString = Tcl_GetString(objv[2]); | |||
2064 | ||||
2065 | if (strcmp(valueString, "unlimited") == 0) { | |||
2066 | value = (Tcl_WideInt)RLIM_INFINITY((__rlim_t) -1); | |||
2067 | result = TCL_OK0; | |||
2068 | } | |||
2069 | } | |||
2070 | if (result == TCL_OK0) { | |||
2071 | rc = getrlimit(resource[opt], &rlimit); | |||
2072 | if (rc > -1) { | |||
2073 | rlimit.rlim_cur = (rlim_t)value; | |||
2074 | rc = setrlimit(resource[opt], &rlimit); | |||
2075 | } | |||
2076 | if (rc == -1) { | |||
2077 | Ns_TclPrintfResult(interp, "could not set limit"); | |||
2078 | result = TCL_ERROR1; | |||
2079 | } | |||
2080 | } | |||
2081 | } else { | |||
2082 | Ns_TclPrintfResult(interp, "wrong # of arguments"); | |||
2083 | result = TCL_ERROR1; | |||
2084 | } | |||
2085 | ||||
2086 | if (result == TCL_OK0) { | |||
2087 | Tcl_Obj *listPtr = Tcl_NewListObj(0, NULL((void*)0)); | |||
2088 | ||||
2089 | Tcl_ListObjAppendElement(interp, listPtr, GetLimitObj(rlimit.rlim_cur)); | |||
2090 | Tcl_ListObjAppendElement(interp, listPtr, GetLimitObj(rlimit.rlim_max)); | |||
2091 | Tcl_SetObjResult(interp, listPtr); | |||
2092 | result = TCL_OK0; | |||
2093 | } | |||
2094 | ||||
2095 | return result; | |||
2096 | #else | |||
2097 | return TCL_OK0; | |||
2098 | #endif | |||
2099 | } | |||
2100 | ||||
2101 | ||||
2102 | /* | |||
2103 | *---------------------------------------------------------------------- | |||
2104 | * | |||
2105 | * NsTclHashObjCmd -- | |||
2106 | * | |||
2107 | * Produce a numeric hash value from a given string. This function uses | |||
2108 | * the Tcl built-in hash function which is commented in Tcl as follows: | |||
2109 | * | |||
2110 | * I tried a zillion different hash functions and asked many other | |||
2111 | * people for advice. Many people had their own favorite functions, | |||
2112 | * all different, but no-one had much idea why they were good ones. I | |||
2113 | * chose the one below (multiply by 9 and add new character) because | |||
2114 | * of the following reasons: | |||
2115 | * | |||
2116 | * 1. Multiplying by 10 is perfect for keys that are decimal strings, and | |||
2117 | * multiplying by 9 is just about as good. | |||
2118 | * 2. Times-9 is (shift-left-3) plus (old). This means that each | |||
2119 | * character's bits hang around in the low-order bits of the hash value | |||
2120 | * for ever, plus they spread fairly rapidly up to the high-order bits | |||
2121 | * to fill out the hash value. This seems works well both for decimal | |||
2122 | * and non-decimal strings, but isn't strong against maliciously-chosen | |||
2123 | * keys. | |||
2124 | * | |||
2125 | * Note that this function is very weak against malicious strings; | |||
2126 | * it is very easy to generate multiple keys that have the same | |||
2127 | * hashcode. On the other hand, that hardly ever actually occurs and | |||
2128 | * this function *is* very cheap, even by comparison with | |||
2129 | * industry-standard hashes like FNV. | |||
2130 | * | |||
2131 | * Implements "ns_hash". | |||
2132 | * | |||
2133 | * Results: | |||
2134 | * Numeric hash value. | |||
2135 | * | |||
2136 | * Side effects: | |||
2137 | * None. | |||
2138 | * | |||
2139 | *---------------------------------------------------------------------- | |||
2140 | */ | |||
2141 | int | |||
2142 | NsTclHashObjCmd(ClientData UNUSED(clientData)UNUSED_clientData __attribute__((__unused__)), Tcl_Interp *interp, int objc, Tcl_Obj *const* objv) | |||
2143 | { | |||
2144 | int result = TCL_OK0; | |||
2145 | char *inputString = (char*)""; | |||
2146 | Ns_ObjvSpec args[] = { | |||
2147 | {"string", Ns_ObjvString, &inputString, NULL((void*)0)}, | |||
2148 | {NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0)} | |||
2149 | }; | |||
2150 | ||||
2151 | if (Ns_ParseObjv(NULL((void*)0), args, interp, 1, objc, objv) != NS_OK) { | |||
2152 | result = TCL_ERROR1; | |||
2153 | } else { | |||
2154 | unsigned int hashValue; | |||
2155 | ||||
2156 | if ((hashValue = UCHAR(*inputString)((unsigned char)(*inputString))) != 0) { | |||
2157 | char c; | |||
2158 | ||||
2159 | while ((c = *++inputString) != 0) { | |||
2160 | hashValue += (hashValue << 3) + UCHAR(c)((unsigned char)(c)); | |||
2161 | } | |||
2162 | } | |||
2163 | Tcl_SetObjResult(interp, Tcl_NewLongObj(hashValue)); | |||
2164 | } | |||
2165 | return result; | |||
2166 | ||||
2167 | } | |||
2168 | ||||
2169 | /* | |||
2170 | *---------------------------------------------------------------------- | |||
2171 | * | |||
2172 | * NsTclValidUtf8ObjCmd -- | |||
2173 | * | |||
2174 | * Check, if the input string is valid UTF-8. | |||
2175 | * | |||
2176 | * Implements "ns_valid_utf8". | |||
2177 | * | |||
2178 | * Results: | |||
2179 | * Tcl result code | |||
2180 | * | |||
2181 | * Side effects: | |||
2182 | * None | |||
2183 | * | |||
2184 | *---------------------------------------------------------------------- | |||
2185 | */ | |||
2186 | int | |||
2187 | NsTclValidUtf8ObjCmd(ClientData UNUSED(clientData)UNUSED_clientData __attribute__((__unused__)), Tcl_Interp *interp, int objc, Tcl_Obj *const* objv) | |||
2188 | { | |||
2189 | int result; | |||
2190 | Tcl_Obj *stringObj = NULL((void*)0), *errorVarnameObj = NULL((void*)0); | |||
2191 | Ns_ObjvSpec args[] = { | |||
2192 | {"string", Ns_ObjvObj, &stringObj, NULL((void*)0)}, | |||
2193 | {"?error", Ns_ObjvObj, &errorVarnameObj, NULL((void*)0)}, | |||
2194 | {NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0)} | |||
2195 | }; | |||
2196 | ||||
2197 | if (Ns_ParseObjv(NULL((void*)0), args, interp, 1, objc, objv) != NS_OK) { | |||
2198 | result = TCL_ERROR1; | |||
2199 | } else { | |||
2200 | Tcl_DString stringDS, errorDS; | |||
2201 | int stringLength; | |||
2202 | const unsigned char *bytes; | |||
2203 | bool_Bool isValid; | |||
2204 | ||||
2205 | Tcl_DStringInit(&stringDS); | |||
2206 | bytes = Ns_GetBinaryString(stringObj, 1, &stringLength, &stringDS); | |||
2207 | isValid = Ns_Valid_UTF8(bytes, (size_t)stringLength, &errorDS); | |||
2208 | ||||
2209 | if (!isValid) { | |||
2210 | if (errorVarnameObj != NULL((void*)0)) { | |||
2211 | Tcl_DString outputDS; | |||
2212 | ||||
2213 | Tcl_DStringInit(&outputDS); | |||
2214 | Ns_DStringAppendPrintable(&outputDS, NS_FALSE0, | |||
2215 | errorDS.string, (size_t)errorDS.length); | |||
2216 | ||||
2217 | Tcl_ObjSetVar2(interp, errorVarnameObj, NULL((void*)0), | |||
2218 | Tcl_NewStringObj(outputDS.string, outputDS.length), | |||
2219 | 0); | |||
2220 | Tcl_DStringFree(&outputDS); | |||
2221 | } | |||
2222 | Tcl_DStringFree(&errorDS); | |||
2223 | } | |||
2224 | ||||
2225 | Tcl_SetObjResult(interp, Tcl_NewBooleanObj(isValid)Tcl_NewIntObj((isValid)!=0)); | |||
2226 | Tcl_DStringFree(&stringDS); | |||
2227 | result = TCL_OK0; | |||
2228 | } | |||
2229 | return result; | |||
2230 | } | |||
2231 | ||||
2232 | #if 0 | |||
2233 | set s "hello world" | |||
2234 | time {time {ns_valid_utf8 $s} 1000} 1000 ;# 251mms ;# 229 | |||
2235 | set s [string repeat x 1000] | |||
2236 | time {time {ns_valid_utf8 $s} 1000} 1000 ;# 4328.282139999999 ; 1535.6498230000002 | |||
2237 | ||||
2238 | ns_valid_utf8 [encoding convertto utf-8 motörhead] | |||
2239 | ns_valid_utf8 "foo\x85" | |||
2240 | ns_valid_utf8 [encoding convertto utf-8 "foo\x85"] | |||
2241 | ns_valid_utf8 "foo\xc3\x85" | |||
2242 | ||||
2243 | #endif | |||
2244 | ||||
2245 | /* | |||
2246 | *---------------------------------------------------------------------- | |||
2247 | * | |||
2248 | * NsTclBaseUnitObjCmd -- | |||
2249 | * | |||
2250 | * Convert the provided argument to its base unit | |||
2251 | * | |||
2252 | * Implements "ns_baseunit". | |||
2253 | * | |||
2254 | * Results: | |||
2255 | * Tcl result code | |||
2256 | * | |||
2257 | * Side effects: | |||
2258 | * None | |||
2259 | * | |||
2260 | *---------------------------------------------------------------------- | |||
2261 | */ | |||
2262 | int | |||
2263 | NsTclBaseUnitObjCmd(ClientData UNUSED(clientData)UNUSED_clientData __attribute__((__unused__)), Tcl_Interp *interp, int objc, Tcl_Obj *const* objv) | |||
2264 | { | |||
2265 | int result; | |||
2266 | Tcl_WideInt memUnitValue = -1; | |||
2267 | Ns_Time *tPtr = NULL((void*)0); | |||
2268 | Ns_ObjvSpec opts[] = { | |||
2269 | {"-size", Ns_ObjvMemUnit, &memUnitValue, NULL((void*)0)}, | |||
2270 | {"-time", Ns_ObjvTime, &tPtr, NULL((void*)0)}, | |||
2271 | {NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0)} | |||
2272 | }; | |||
2273 | ||||
2274 | if (Ns_ParseObjv(opts, NULL((void*)0), interp, 1, objc, objv) != NS_OK) { | |||
2275 | result = TCL_ERROR1; | |||
2276 | ||||
2277 | } else if (objc != 3) { | |||
2278 | Ns_TclPrintfResult(interp, "either -size or -time must be specified"); | |||
2279 | result = TCL_ERROR1; | |||
2280 | ||||
2281 | } else { | |||
2282 | const char *argString = Tcl_GetString(objv[1]); | |||
2283 | ||||
2284 | if (argString[1] == 's') { | |||
2285 | Tcl_SetObjResult(interp, Tcl_NewWideIntObj(memUnitValue)); | |||
2286 | result = TCL_OK0; | |||
2287 | ||||
2288 | } else if (argString[1] == 't') { | |||
2289 | Tcl_DString ds, *dsPtr = &ds; | |||
2290 | ||||
2291 | Tcl_DStringInit(dsPtr); | |||
2292 | Ns_DStringAppendTime(dsPtr, tPtr); | |||
2293 | Tcl_DStringResult(interp, dsPtr); | |||
2294 | result = TCL_OK0; | |||
2295 | ||||
2296 | } else { | |||
2297 | Ns_TclPrintfResult(interp, "either -size or -time must be specified"); | |||
2298 | result = TCL_ERROR1; | |||
2299 | } | |||
2300 | } | |||
2301 | return result; | |||
2302 | } | |||
2303 | #if 0 | |||
2304 | ns_baseunit -size 1KB | |||
2305 | #endif | |||
2306 | ||||
2307 | /* | |||
2308 | *---------------------------------------------------------------------- | |||
2309 | * | |||
2310 | * NsTclStrcollObjCmd -- | |||
2311 | * | |||
2312 | * Compare two strings based on the POSIX strcoll_l() command. | |||
2313 | * | |||
2314 | * Implements "ns_strcoll". | |||
2315 | * | |||
2316 | * Results: | |||
2317 | * Tcl result code | |||
2318 | * | |||
2319 | * Side effects: | |||
2320 | * None | |||
2321 | * | |||
2322 | *---------------------------------------------------------------------- | |||
2323 | */ | |||
2324 | int | |||
2325 | NsTclStrcollObjCmd(ClientData UNUSED(clientData)UNUSED_clientData __attribute__((__unused__)), Tcl_Interp *interp, int objc, Tcl_Obj *const* objv) | |||
2326 | { | |||
2327 | int result = TCL_OK0; | |||
2328 | Tcl_Obj *arg1Obj, *arg2Obj; | |||
2329 | char *localeString = NULL((void*)0); | |||
2330 | Ns_ObjvSpec opts[] = { | |||
2331 | {"-locale", Ns_ObjvString, &localeString, NULL((void*)0)}, | |||
2332 | {"--", Ns_ObjvBreak, NULL((void*)0), NULL((void*)0)}, | |||
2333 | {NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0)} | |||
2334 | }; | |||
2335 | ||||
2336 | Ns_ObjvSpec args[] = { | |||
2337 | {"string1", Ns_ObjvObj, &arg1Obj, NULL((void*)0)}, | |||
2338 | {"string2", Ns_ObjvObj, &arg2Obj, NULL((void*)0)}, | |||
2339 | {NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0)} | |||
2340 | }; | |||
2341 | ||||
2342 | if (Ns_ParseObjv(opts, args, interp, 1, objc, objv) != NS_OK) { | |||
2343 | result = TCL_ERROR1; | |||
2344 | ||||
2345 | } else { | |||
2346 | locale_t locale = 0; | |||
2347 | ||||
2348 | if (localeString != NULL((void*)0)) { | |||
2349 | #ifdef _WIN32 | |||
2350 | locale = _create_locale(LC_COLLATE3, localeString); | |||
2351 | #else | |||
2352 | locale = newlocale(LC_COLLATE_MASK(1 << 3), localeString, (locale_t)0); | |||
2353 | #endif | |||
2354 | if (locale == 0) { | |||
2355 | Ns_TclPrintfResult(interp, "specified locale '%s' is not available", localeString); | |||
2356 | result = TCL_ERROR1; | |||
2357 | } | |||
2358 | } | |||
2359 | ||||
2360 | if (result == TCL_OK0) { | |||
2361 | Tcl_DString ds1, ds2, *ds1Ptr = &ds1, *ds2Ptr = &ds2; | |||
2362 | int length1, length2, comparisonValue; | |||
2363 | const char *string1, *string2; | |||
2364 | ||||
2365 | Tcl_DStringInit(ds1Ptr); | |||
2366 | Tcl_DStringInit(ds2Ptr); | |||
2367 | ||||
2368 | string1 = Tcl_GetStringFromObj(arg1Obj, &length1); | |||
2369 | string2 = Tcl_GetStringFromObj(arg2Obj, &length2); | |||
2370 | Tcl_UtfToExternalDString(NULL((void*)0), string1, length1, ds1Ptr); | |||
2371 | Tcl_UtfToExternalDString(NULL((void*)0), string2, length2, ds2Ptr); | |||
2372 | ||||
2373 | errno(*__errno_location ()) = 0; | |||
2374 | comparisonValue = strcoll_l(ds1Ptr->string, ds2Ptr->string, | |||
2375 | locale != 0 ? locale : nsconf.locale); | |||
2376 | ||||
2377 | Ns_Log(Debug, "ns_collate: compare '%s' and '%s' using %s (%p) -> %d (%d)", | |||
2378 | ds1Ptr->string, ds2Ptr->string, | |||
2379 | localeString == NULL((void*)0) ? "default locale" : localeString, | |||
2380 | (void*)locale, comparisonValue, errno(*__errno_location ())); | |||
2381 | ||||
2382 | Tcl_SetObjResult(interp, Tcl_NewIntObj(comparisonValue)); | |||
2383 | ||||
2384 | Tcl_DStringFree(ds1Ptr); | |||
2385 | Tcl_DStringFree(ds2Ptr); | |||
2386 | } | |||
2387 | ||||
2388 | if (locale != 0) { | |||
2389 | #ifdef _WIN32 | |||
2390 | _free_locale(locale); | |||
2391 | #else | |||
2392 | freelocale(locale); | |||
2393 | #endif | |||
2394 | } | |||
2395 | } | |||
2396 | return result; | |||
2397 | } | |||
2398 | ||||
2399 | ||||
2400 | ||||
2401 | /* | |||
2402 | *---------------------------------------------------------------------- | |||
2403 | * | |||
2404 | * NsTclSubnetmatchObjCmd -- | |||
2405 | * | |||
2406 | * Checks whether an IP address (IPv4 or IPV6) is in a given CIDR | |||
2407 | * (Classless Inter-Domain Routing) range. CIDR supports variable-length | |||
2408 | * subnet masking and specifies an IPv6 or IPv6 address, a slash ('/') | |||
2409 | * character, and a decimal number representing the significant bits of | |||
2410 | * the IP address. | |||
2411 | * | |||
2412 | * Implements "ns_subnetmatch". | |||
2413 | * | |||
2414 | * Results: | |||
2415 | * Tcl result code | |||
2416 | * | |||
2417 | * Side effects: | |||
2418 | * None | |||
2419 | * | |||
2420 | *---------------------------------------------------------------------- | |||
2421 | */ | |||
2422 | int | |||
2423 | NsTclSubnetmatchObjCmd(ClientData UNUSED(clientData)UNUSED_clientData __attribute__((__unused__)), Tcl_Interp *interp, int objc, Tcl_Obj *const* objv) | |||
2424 | { | |||
2425 | int result = TCL_OK0; | |||
2426 | char *cidrString, *ipString; | |||
2427 | unsigned int nrBits = 0; | |||
2428 | struct NS_SOCKADDR_STORAGEsockaddr_storage ip, ip2, mask; | |||
2429 | struct sockaddr | |||
2430 | *ipPtr = (struct sockaddr *)&ip, | |||
2431 | *ipPtr2 = (struct sockaddr *)&ip2, | |||
2432 | *maskPtr = (struct sockaddr *)&mask; | |||
2433 | ||||
2434 | Ns_ObjvSpec args[] = { | |||
2435 | {"cidr", Ns_ObjvString, &cidrString, NULL((void*)0)}, | |||
2436 | {"ipaddr", Ns_ObjvString, &ipString, NULL((void*)0)}, | |||
2437 | {NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0)} | |||
2438 | }; | |||
2439 | ||||
2440 | if (Ns_ParseObjv(NULL((void*)0), args, interp, 1, objc, objv) != NS_OK) { | |||
2441 | result = TCL_ERROR1; | |||
2442 | ||||
2443 | } else if (ns_inet_pton(ipPtr, ipString) != 1) { | |||
2444 | Ns_TclPrintfResult(interp, "'%s' is not a valid IPv4 or IPv6 address", ipString); | |||
2445 | result = TCL_ERROR1; | |||
2446 | ||||
2447 | } else if (Ns_SockaddrParseIPMask(interp, cidrString, ipPtr2, maskPtr, &nrBits) != NS_OK) { | |||
2448 | Ns_TclPrintfResult(interp, "'%s' is not a valid CIDR string for IPv4 or IPv6", cidrString); | |||
2449 | result = TCL_ERROR1; | |||
2450 | ||||
2451 | } else { | |||
2452 | bool_Bool success = (nrBits == 0 || Ns_SockaddrMaskedMatch(ipPtr, maskPtr, ipPtr2)); | |||
2453 | ||||
2454 | Tcl_SetObjResult(interp, Tcl_NewBooleanObj(success)Tcl_NewIntObj((success)!=0)); | |||
2455 | } | |||
2456 | return result; | |||
2457 | } | |||
2458 | #if 0 | |||
2459 | ns_subnetmatch 137.208.0.0/16 137.208.116.31 | |||
2460 | #endif | |||
2461 | ||||
2462 | /* | |||
2463 | * Local Variables: | |||
2464 | * mode: c | |||
2465 | * c-basic-offset: 4 | |||
2466 | * fill-column: 78 | |||
2467 | * indent-tabs-mode: nil | |||
2468 | * End: | |||
2469 | */ |