File: | d/tclmisc.c |
Warning: | line 1814, column 5 Duplicate code detected |
Note: | line 1815, column 5 Similar code here |
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) ); |
Duplicate code detected | |
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) ); |
Similar code here | |
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 | */ |