ArchWizard

DGD/

source navigation ]
diff markup ]
identifier search ]
file search ]
Version: [ 1.0.a0 ] [ 1.1 ] [ 1.2 ] [ 1.2p1 ] [ 1.2p2 ] [ 1.2p3 ] [ 1.2p4 ] [ 1.2.151 ]

  1 # ifndef FUNCDEF
  2 # define INCLUDE_CTYPE
  3 # include "kfun.h"
  4 # include "parse.h"
  5 # endif
  6 
  7 
  8 # ifdef FUNCDEF
  9 FUNCDEF("crypt", kf_crypt, pt_crypt)
 10 # else
 11 char pt_crypt[] = { C_TYPECHECKED | C_STATIC | C_KFUN_VARARGS, T_STRING, 2,
 12                     T_STRING | T_VARARGS, T_STRING };
 13 
 14 /*
 15  * NAME:        kfun->crypt()
 16  * DESCRIPTION: encrypt a string
 17  */
 18 int kf_crypt(f, nargs)
 19 register frame *f;
 20 int nargs;
 21 {
 22     static char salts[] =
 23             "0123456789./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
 24     char salt[3], *p;
 25     
 26     if (nargs == 2 && f->sp->u.string->len >= 2) {
 27         /* fixed salt */
 28         salt[0] = f->sp->u.string->text[0];
 29         salt[1] = f->sp->u.string->text[1];
 30     } else {
 31         /* random salt */
 32         salt[0] = salts[P_random() % 64];
 33         salt[1] = salts[P_random() % 64];
 34     }
 35     salt[2] = '\0';
 36     if (nargs == 2) {
 37         str_del((f->sp++)->u.string);
 38     }
 39 
 40     i_add_ticks(f, 400);
 41     p = P_crypt(f->sp->u.string->text, salt);
 42     str_del(f->sp->u.string);
 43     PUT_STR(f->sp, str_new(p, (long) strlen(p)));
 44     return 0;
 45 }
 46 # endif
 47 
 48 
 49 # ifdef FUNCDEF
 50 FUNCDEF("ctime", kf_ctime, pt_ctime)
 51 # else
 52 char pt_ctime[] = { C_TYPECHECKED | C_STATIC, T_STRING, 1, T_INT };
 53 
 54 /*
 55  * NAME:        kfun->ctime()
 56  * DESCRIPTION: convert a time value to a string
 57  */
 58 int kf_ctime(f)
 59 frame *f;
 60 {
 61     char buf[26];
 62 
 63     i_add_ticks(f, 5);
 64     P_ctime(buf, f->sp->u.number);
 65     PUT_STRVAL(f->sp, str_new(buf, 24L));
 66 
 67     return 0;
 68 }
 69 # endif
 70 
 71 
 72 # ifdef FUNCDEF
 73 FUNCDEF("explode", kf_explode, pt_explode)
 74 # else
 75 char pt_explode[] = { C_TYPECHECKED | C_STATIC, T_STRING | (1 << REFSHIFT), 2,
 76                       T_STRING, T_STRING };
 77 
 78 /*
 79  * NAME:        kfun->explode()
 80  * DESCRIPTION: explode a string
 81  */
 82 int kf_explode(f)
 83 register frame *f;
 84 {
 85     register unsigned int len, slen, size;
 86     register char *p, *s;
 87     register value *v;
 88     array *a;
 89 
 90     p = f->sp[1].u.string->text;
 91     len = f->sp[1].u.string->len;
 92     s = f->sp->u.string->text;
 93     slen = f->sp->u.string->len;
 94 
 95     if (len == 0) {
 96         /*
 97          * exploding "" always gives an empty array
 98          */
 99         a = arr_new(f->data, 0L);
100     } else if (slen == 0) {
101         /*
102          * the sepatator is ""; split string into single characters
103          */
104         a = arr_new(f->data, (long) len);
105         for (v = a->elts; len > 0; v++, --len) {
106             PUT_STRVAL(v, str_new(p, 1L));
107             p++;
108         }
109     } else {
110         /*
111          * split up the string with the separator
112          */
113         size = 1;
114         if (len >= slen && memcmp(p, s, slen) == 0) {
115             /* skip leading separator */
116             p += slen;
117             len -= slen;
118         }
119         while (len > slen) {
120             if (memcmp(p, s, slen) == 0) {
121                 /* separator found */
122                 p += slen;
123                 len -= slen;
124                 size++;
125             } else {
126                 /* next char */
127                 p++;
128                 --len;
129             }
130         }
131 
132         a = arr_new(f->data, (long) size);
133         v = a->elts;
134 
135         p = f->sp[1].u.string->text;
136         len = f->sp[1].u.string->len;
137         size = 0;
138         if (len > slen && memcmp(p, s, slen) == 0) {
139             /* skip leading separator */
140             p += slen;
141             len -= slen;
142         }
143         while (len > slen) {
144             if (memcmp(p, s, slen) == 0) {
145                 /* separator found */
146                 PUT_STRVAL(v, str_new(p - size, (long) size));
147                 v++;
148                 p += slen;
149                 len -= slen;
150                 size = 0;
151             } else {
152                 /* next char */
153                 p++;
154                 --len;
155                 size++;
156             }
157         }
158         if (len != slen || memcmp(p, s, slen) != 0) {
159             /* remainder isn't a sepatator */
160             size += len;
161             p += len;
162         }
163         /* final array element */
164         PUT_STRVAL(v, str_new(p - size, (long) size));
165     }
166 
167     str_del((f->sp++)->u.string);
168     str_del(f->sp->u.string);
169     PUT_ARRVAL(f->sp, a);
170     i_add_ticks(f, (Int) 2 * a->size);
171 
172     return 0;
173 }
174 # endif
175 
176 
177 # ifdef FUNCDEF
178 FUNCDEF("implode", kf_implode, pt_implode)
179 # else
180 char pt_implode[] = { C_TYPECHECKED | C_STATIC, T_STRING, 2,
181                       T_STRING | (1 << REFSHIFT), T_STRING };
182 
183 /*
184  * NAME:        kfun->implode()
185  * DESCRIPTION: implode an array
186  */
187 int kf_implode(f)
188 register frame *f;
189 {
190     register long len;
191     register unsigned int i, slen;
192     register char *p, *s;
193     register value *v;
194     string *str;
195 
196     s = f->sp->u.string->text;
197     slen = f->sp->u.string->len;
198 
199     /* first, determine the size of the imploded string */
200     i = f->sp[1].u.array->size;
201     i_add_ticks(f, i);
202     if (i != 0) {
203         len = (i - 1) * (long) slen;    /* size of all separators */
204         for (v = d_get_elts(f->sp[1].u.array); i > 0; v++, --i) {
205             if (v->type != T_STRING) {
206                 /* not a (string *) */
207                 return 1;
208             }
209             len += v->u.string->len;
210         }
211         str = str_new((char *) NULL, len);
212 
213         /* create the imploded string */
214         p = str->text;
215         for (i = f->sp[1].u.array->size, v -= i; i > 1; --i, v++) {
216             /* copy array part */
217             memcpy(p, v->u.string->text, v->u.string->len);
218             p += v->u.string->len;
219             /* copy separator */
220             memcpy(p, s, slen);
221             p += slen;
222         }
223         /* copy final array part */
224         memcpy(p, v->u.string->text, v->u.string->len);
225     } else {
226         /* zero size array gives zero size string */
227         str = str_new((char *) NULL, 0L);
228     }
229 
230     str_del((f->sp++)->u.string);
231     arr_del(f->sp->u.array);
232     PUT_STRVAL(f->sp, str);
233     return 0;
234 }
235 # endif
236 
237 
238 # ifdef FUNCDEF
239 FUNCDEF("random", kf_random, pt_random)
240 # else
241 char pt_random[] = { C_TYPECHECKED | C_STATIC, T_INT, 1, T_INT };
242 
243 /*
244  * NAME:        kfun->random()
245  * DESCRIPTION: return a random number
246  */
247 int kf_random(f)
248 register frame *f;
249 {
250     i_add_ticks(f, 1);
251     PUT_INT(f->sp, (f->sp->u.number > 0) ? P_random() % f->sp->u.number : 0);
252     return 0;
253 }
254 # endif
255 
256 
257 # ifdef FUNCDEF
258 FUNCDEF("sscanf", kf_sscanf, pt_sscanf)
259 # else
260 char pt_sscanf[] = { C_TYPECHECKED | C_STATIC | C_KFUN_VARARGS, T_INT, 3,
261                      T_STRING, T_STRING, T_LVALUE | T_ELLIPSIS };
262 
263 /*
264  * NAME:        match
265  * DESCRIPTION: match a string possibly including %%, up to the next %[sdfc] or
266  *              the end of the string
267  */
268 static bool match(f, s, flenp, slenp)
269 register char *f, *s;
270 unsigned int *flenp, *slenp;
271 {
272     register char *p;
273     register unsigned int flen, slen;
274 
275     flen = *flenp;
276     slen = *slenp;
277 
278     while (flen > 0) {
279         /* look for first % */
280         p = (char *) memchr(f, '%', flen);
281 
282         if (p == (char *) NULL) {
283             /* no remaining % */
284             if (memcmp(f, s, flen) == 0) {
285                 *slenp -= slen - flen;
286                 return TRUE;
287             } else {
288                 return FALSE;   /* no match */
289             }
290         }
291 
292         if (p[1] == '%') {
293             /* %% */
294             if (memcmp(f, s, ++p - f) == 0) {
295                 /* matched up to and including the first % */
296                 s += p - f;
297                 slen -= p - f;
298                 flen -= ++p - f;
299                 f = p;
300             } else {
301                 return FALSE;   /* no match */
302             }
303         } else if (memcmp(f, s, p - f) == 0) {
304             /* matched up to the first % */
305             *flenp -= flen - (p - f);
306             *slenp -= slen - (p - f);
307             return TRUE;
308         } else {
309             return FALSE;       /* no match */
310         }
311     }
312 
313     *slenp -= slen;
314     return TRUE;
315 }
316 
317 /*
318  * NAME:        kfun->sscanf()
319  * DESCRIPTION: scan a string
320  */
321 int kf_sscanf(f, nargs)
322 register frame *f;
323 int nargs;
324 {
325     register unsigned int flen, slen, size;
326     register char *format, *x;
327     unsigned int fl, sl;
328     int matches;
329     char *s;
330     Int i;
331     xfloat flt;
332     bool skip;
333 
334     if (nargs > MAX_LOCALS + 2) {
335         return 4;
336     }
337     s = f->sp[nargs - 1].u.string->text;
338     slen = f->sp[nargs - 1].u.string->len;
339     nargs -= 2;
340     format = f->sp[nargs].u.string->text;
341     flen = f->sp[nargs].u.string->len;
342     i_reverse(f, nargs);
343 
344     i_add_ticks(f, 8 * nargs);
345     matches = 0;
346 
347     while (flen > 0) {
348         if (format[0] != '%' || format[1] == '%') {
349             /* match initial part */
350             fl = flen;
351             sl = slen;
352             if (!match(format, s, &fl, &sl) || fl == flen) {
353                 goto no_match;
354             }
355             format += fl;
356             flen -= fl;
357             s += sl;
358             slen -= sl;
359         }
360 
361         /* skip first % */
362         format++;
363         --flen;
364 
365         /*
366          * check for %*
367          */
368         if (*format == '*') {
369             /* no assignment */
370             format++;
371             --flen;
372             skip = TRUE;
373         } else {
374             skip = FALSE;
375         }
376 
377         --flen;
378         switch (*format++) {
379         case 's':
380             /* %s */
381             if (format[0] == '%' && format[1] != '%') {
382                 switch ((format[1] == '*') ? format[2] : format[1]) {
383                 case 'd':
384                     /*
385                      * %s%d
386                      */
387                     size = slen;
388                     x = s;
389                     while (!isdigit(*x)) {
390                         if (slen == 0) {
391                             goto no_match;
392                         }
393                         if (x[0] == '-' && isdigit(x[1])) {
394                             break;
395                         }
396                         x++;
397                         --slen;
398                     }
399                     size -= slen;
400                     break;
401 
402                 case 'f':
403                     /*
404                      * %s%f
405                      */
406                     size = slen;
407                     x = s;
408                     while (!isdigit(*x)) {
409                         if (slen == 0) {
410                             goto no_match;
411                         }
412                         if ((x[0] == '-' || x[0] == '.') && isdigit(x[1])) {
413                             break;
414                         }
415                         x++;
416                         --slen;
417                     }
418                     size -= slen;
419                     break;
420 
421                 default:
422                     error("Bad sscanf format string");
423                 }
424             } else {
425                 /*
426                  * %s followed by non-%
427                  */
428                 if (flen == 0) {
429                     /* match whole string */
430                     size = slen;
431                     x = s + slen;
432                     slen = 0;
433                 } else {
434                     /* get # of chars to match after string */
435                     for (x = format, size = 0; (x - format) != flen;
436                          x++, size++) {
437                         x = (char *) memchr(x, '%', flen - (x - format));
438                         if (x == (char *) NULL) {
439                             x = format + flen;
440                             break;
441                         } else if (x[1] != '%') {
442                             break;
443                         }
444                     }
445                     size = (x - format) - size;
446 
447                     x = s;
448                     for (;;) {
449                         sl = slen - (x - s);
450                         if (sl < size) {
451                             goto no_match;
452                         }
453                         x = (char *) memchr(x, format[0], sl - size + 1);
454                         if (x == (char *) NULL) {
455                             goto no_match;
456                         }
457                         fl = flen;
458                         if (match(format, x, &fl, &sl)) {
459                             format += fl;
460                             flen -= fl;
461                             size = x - s;
462                             x += sl;
463                             slen -= size + sl;
464                             break;
465                         }
466                         x++;
467                     }
468                 }
469             }
470 
471             if (!skip) {
472                 if (nargs == 0) {
473                     error("No lvalue for %%s");
474                 }
475                 --nargs;
476                 PUSH_STRVAL(f, str_new(s, (long) size));
477                 i_store(f);
478                 f->sp->u.string->ref--;
479                 f->sp += 2;
480             }
481             s = x;
482             break;
483 
484         case 'd':
485             /* %d */
486             x = s;
487             i = strtol(s, &s, 10);
488             if (s == x) {
489                 goto no_match;
490             }
491             slen -= (s - x);
492 
493             if (!skip) {
494                 if (nargs == 0) {
495                     error("No lvalue for %%d");
496                 }
497                 --nargs;
498                 PUSH_INTVAL(f, i);
499                 i_store(f);
500                 f->sp += 2;
501             }
502             break;
503 
504         case 'f':
505             /* %f */
506             x = s;
507             if (!flt_atof(&s, &flt) || s == x) {
508                 goto no_match;
509             }
510             slen -= (s - x);
511 
512             if (!skip) {
513                 if (nargs == 0) {
514                     error("No lvalue for %%f");
515                 }
516                 --nargs;
517                 PUSH_FLTVAL(f, flt);
518                 i_store(f);
519                 f->sp += 2;
520             }
521             break;
522 
523         case 'c':
524             /* %c */
525             if (slen == 0) {
526                 goto no_match;
527             }
528             if (!skip) {
529                 if (nargs == 0) {
530                     error("No lvalue for %%c");
531                 }
532                 --nargs;
533                 PUSH_INTVAL(f, UCHAR(*s));
534                 i_store(f);
535                 f->sp += 2;
536             }
537             s++;
538             --slen;
539             break;
540 
541         default:
542             error("Bad sscanf format string");
543         }
544         matches++;
545     }
546 
547 no_match:
548     if (nargs > 0) {
549         i_pop(f, nargs);        /* pop superfluous arguments */
550     }
551     str_del((f->sp++)->u.string);
552     str_del(f->sp->u.string);
553     PUT_INTVAL(f->sp, matches);
554     return 0;
555 }
556 # endif
557 
558 
559 # ifdef FUNCDEF
560 FUNCDEF("parse_string", kf_parse_string, pt_parse_string)
561 # else
562 char pt_parse_string[] = { C_TYPECHECKED | C_STATIC | C_KFUN_VARARGS,
563                            T_MIXED | (1 << REFSHIFT), 3,
564                            T_STRING, T_STRING | T_VARARGS, T_INT };
565 
566 /*
567  * NAME:        kfun->parse_string()
568  * DESCRIPTION: parse a string
569  */
570 int kf_parse_string(f, nargs)
571 register frame *f;
572 int nargs;
573 {
574     Int maxalt;
575     array *a;
576 
577     if (nargs > 2) {
578         maxalt = (f->sp++)->u.number + 1;
579         if (maxalt <= 0) {
580             return 3;
581         }
582     } else {
583         maxalt = 1;     /* default: just one valid parse tree */
584     }
585 
586     if (OBJR(f->oindex)->flags & O_SPECIAL) {
587         error("parse_string() from special purpose object");
588     }
589 
590     a = ps_parse_string(f, f->sp[1].u.string, f->sp->u.string, maxalt);
591     str_del((f->sp++)->u.string);
592     str_del(f->sp->u.string);
593 
594     if (a != (array *) NULL) {
595         /* return parse tree */
596         PUT_ARRVAL(f->sp, a);
597     } else {
598         /* parsing failed */
599         *f->sp = nil_value;
600     }
601     return 0;
602 }
603 # endif
604 
605 
606 # ifdef FUNCDEF
607 FUNCDEF("hash_crc16", kf_hash_crc16, pt_hash_crc16)
608 # else
609 char pt_hash_crc16[] = { C_TYPECHECKED | C_STATIC | C_KFUN_VARARGS, T_INT, 2,
610                          T_STRING, T_STRING | T_ELLIPSIS };
611 
612 /*
613  * NAME:        kfun->hash_crc16()
614  * DESCRIPTION: Compute a 16 bit cyclic redundancy code for a string.
615  *              Based on "A PAINLESS GUIDE TO CRC ERROR DETECTION ALGORITHMS",
616  *              by Ross N. Williams.
617  *
618  *                  Name:       "CRC-16/CCITT"  (supposedly)
619  *                  Width:      16
620  *                  Poly:       1021            (X^16 + X^12 + X^5 + 1)
621  *                  Init:       FFFF
622  *                  RefIn:      False
623  *                  RefOut:     False
624  *                  XorOut:     0000
625  *                  Check:      29B1
626  */
627 int kf_hash_crc16(f, nargs)
628 register frame *f;
629 int nargs;
630 {
631     static unsigned short crctab[] = {
632         0x0000, 0x2110, 0x4220, 0x6330, 0x8440, 0xa550, 0xc660, 0xe770,
633         0x0881, 0x2991, 0x4aa1, 0x6bb1, 0x8cc1, 0xadd1, 0xcee1, 0xeff1,
634         0x3112, 0x1002, 0x7332, 0x5222, 0xb552, 0x9442, 0xf772, 0xd662,
635         0x3993, 0x1883, 0x7bb3, 0x5aa3, 0xbdd3, 0x9cc3, 0xfff3, 0xdee3,
636         0x6224, 0x4334, 0x2004, 0x0114, 0xe664, 0xc774, 0xa444, 0x8554,
637         0x6aa5, 0x4bb5, 0x2885, 0x0995, 0xeee5, 0xcff5, 0xacc5, 0x8dd5,
638         0x5336, 0x7226, 0x1116, 0x3006, 0xd776, 0xf666, 0x9556, 0xb446,
639         0x5bb7, 0x7aa7, 0x1997, 0x3887, 0xdff7, 0xfee7, 0x9dd7, 0xbcc7,
640         0xc448, 0xe558, 0x8668, 0xa778, 0x4008, 0x6118, 0x0228, 0x2338,
641         0xccc9, 0xedd9, 0x8ee9, 0xaff9, 0x4889, 0x6999, 0x0aa9, 0x2bb9,
642         0xf55a, 0xd44a, 0xb77a, 0x966a, 0x711a, 0x500a, 0x333a, 0x122a,
643         0xfddb, 0xdccb, 0xbffb, 0x9eeb, 0x799b, 0x588b, 0x3bbb, 0x1aab,
644         0xa66c, 0x877c, 0xe44c, 0xc55c, 0x222c, 0x033c, 0x600c, 0x411c,
645         0xaeed, 0x8ffd, 0xeccd, 0xcddd, 0x2aad, 0x0bbd, 0x688d, 0x499d,
646         0x977e, 0xb66e, 0xd55e, 0xf44e, 0x133e, 0x322e, 0x511e, 0x700e,
647         0x9fff, 0xbeef, 0xdddf, 0xfccf, 0x1bbf, 0x3aaf, 0x599f, 0x788f,
648         0x8891, 0xa981, 0xcab1, 0xeba1, 0x0cd1, 0x2dc1, 0x4ef1, 0x6fe1,
649         0x8010, 0xa100, 0xc230, 0xe320, 0x0450, 0x2540, 0x4670, 0x6760,
650         0xb983, 0x9893, 0xfba3, 0xdab3, 0x3dc3, 0x1cd3, 0x7fe3, 0x5ef3,
651         0xb102, 0x9012, 0xf322, 0xd232, 0x3542, 0x1452, 0x7762, 0x5672,
652         0xeab5, 0xcba5, 0xa895, 0x8985, 0x6ef5, 0x4fe5, 0x2cd5, 0x0dc5,
653         0xe234, 0xc324, 0xa014, 0x8104, 0x6674, 0x4764, 0x2454, 0x0544,
654         0xdba7, 0xfab7, 0x9987, 0xb897, 0x5fe7, 0x7ef7, 0x1dc7, 0x3cd7,
655         0xd326, 0xf236, 0x9106, 0xb016, 0x5766, 0x7676, 0x1546, 0x3456,
656         0x4cd9, 0x6dc9, 0x0ef9, 0x2fe9, 0xc899, 0xe989, 0x8ab9, 0xaba9,
657         0x4458, 0x6548, 0x0678, 0x2768, 0xc018, 0xe108, 0x8238, 0xa328,
658         0x7dcb, 0x5cdb, 0x3feb, 0x1efb, 0xf98b, 0xd89b, 0xbbab, 0x9abb,
659         0x754a, 0x545a, 0x376a, 0x167a, 0xf10a, 0xd01a, 0xb32a, 0x923a,
660         0x2efd, 0x0fed, 0x6cdd, 0x4dcd, 0xaabd, 0x8bad, 0xe89d, 0xc98d,
661         0x267c, 0x076c, 0x645c, 0x454c, 0xa23c, 0x832c, 0xe01c, 0xc10c,
662         0x1fef, 0x3eff, 0x5dcf, 0x7cdf, 0x9baf, 0xbabf, 0xd98f, 0xf89f,
663         0x176e, 0x367e, 0x554e, 0x745e, 0x932e, 0xb23e, 0xd10e, 0xf01e
664     };
665     register unsigned short crc;
666     register int i;
667     register ssizet len;
668     register char *p;
669     register Int cost;
670 
671     cost = 0;
672     for (i = nargs; --i >= 0; ) {
673         cost += f->sp[i].u.string->len;
674     }
675     cost = 3 * nargs + (cost >> 2);
676     if (!f->rlim->noticks && f->rlim->ticks <= cost) {
677         f->rlim->ticks = 0;
678         error("Out of ticks");
679     }
680     i_add_ticks(f, cost);
681 
682     crc = 0xffff;
683     for (i = nargs; --i >= 0; ) {
684         p = f->sp[i].u.string->text;
685         for (len = f->sp[i].u.string->len; len != 0; --len) {
686             crc = (crc >> 8) ^ crctab[UCHAR(crc ^ *p++)];
687         }
688         str_del(f->sp[i].u.string);
689     }
690     crc = (crc >> 8) + (crc << 8);
691 
692     f->sp += nargs - 1;
693     PUT_INTVAL(f->sp, crc);
694     return 0;
695 }
696 # endif
697 
698 
699 # ifdef FUNCDEF
700 FUNCDEF("hash_md5", kf_hash_md5, pt_hash_md5)
701 # else
702 char pt_hash_md5[] = { C_TYPECHECKED | C_STATIC | C_KFUN_VARARGS, T_STRING, 2,
703                        T_STRING, T_STRING | T_ELLIPSIS };
704 
705 # define ROTL(x, s)                     ((x << s) | (x >> (32 - s)))
706 # define R1(a, b, c, d, Mj, s, ti)      (a += ((b & c) | (~b & d)) + Mj + ti, \
707                                          a = b + ROTL(a, s))
708 # define R2(a, b, c, d, Mj, s, ti)      (a += ((b & d) | (c & ~d)) + Mj + ti, \
709                                          a = b + ROTL(a, s))
710 # define R3(a, b, c, d, Mj, s, ti)      (a += (b ^ c ^ d) + Mj + ti,          \
711                                          a = b + ROTL(a, s))
712 # define R4(a, b, c, d, Mj, s, ti)      (a += (c ^ (b | ~d)) + Mj + ti,       \
713                                          a = b + ROTL(a, s))
714 
715 /*
716  * NAME:        md5_block()
717  * DESCRIPTION: add another 512 bit block to the message digest
718  */
719 static void md5_block(ABCD, block)
720 Uint *ABCD;
721 register char *block;
722 {
723     Uint M[16];
724     register int i, j;
725     register Uint a, b, c, d;
726 
727     for (i = j = 0; i < 16; i++, j += 4) {
728         M[i] = UCHAR(block[j + 0]) | (UCHAR(block[j + 1]) << 8) |
729                (UCHAR(block[j + 2]) << 16) | (UCHAR(block[j + 3]) << 24);
730     }
731 
732     a = ABCD[0];
733     b = ABCD[1];
734     c = ABCD[2];
735     d = ABCD[3];
736 
737     R1(a, b, c, d, M[ 0],  7, 0xd76aa478);
738     R1(d, a, b, c, M[ 1], 12, 0xe8c7b756);
739     R1(c, d, a, b, M[ 2], 17, 0x242070db);
740     R1(b, c, d, a, M[ 3], 22, 0xc1bdceee);
741     R1(a, b, c, d, M[ 4],  7, 0xf57c0faf);
742     R1(d, a, b, c, M[ 5], 12, 0x4787c62a);
743     R1(c, d, a, b, M[ 6], 17, 0xa8304613);
744     R1(b, c, d, a, M[ 7], 22, 0xfd469501);
745     R1(a, b, c, d, M[ 8],  7, 0x698098d8);
746     R1(d, a, b, c, M[ 9], 12, 0x8b44f7af);
747     R1(c, d, a, b, M[10], 17, 0xffff5bb1);
748     R1(b, c, d, a, M[11], 22, 0x895cd7be);
749     R1(a, b, c, d, M[12],  7, 0x6b901122);
750     R1(d, a, b, c, M[13], 12, 0xfd987193);
751     R1(c, d, a, b, M[14], 17, 0xa679438e);
752     R1(b, c, d, a, M[15], 22, 0x49b40821);
753 
754     R2(a, b, c, d, M[ 1],  5, 0xf61e2562);
755     R2(d, a, b, c, M[ 6],  9, 0xc040b340);
756     R2(c, d, a, b, M[11], 14, 0x265e5a51);
757     R2(b, c, d, a, M[ 0], 20, 0xe9b6c7aa);
758     R2(a, b, c, d, M[ 5],  5, 0xd62f105d);
759     R2(d, a, b, c, M[10],  9, 0x02441453);
760     R2(c, d, a, b, M[15], 14, 0xd8a1e681);
761     R2(b, c, d, a, M[ 4], 20, 0xe7d3fbc8);
762     R2(a, b, c, d, M[ 9],  5, 0x21e1cde6);
763     R2(d, a, b, c, M[14],  9, 0xc33707d6);
764     R2(c, d, a, b, M[ 3], 14, 0xf4d50d87);
765     R2(b, c, d, a, M[ 8], 20, 0x455a14ed);
766     R2(a, b, c, d, M[13],  5, 0xa9e3e905);
767     R2(d, a, b, c, M[ 2],  9, 0xfcefa3f8);
768     R2(c, d, a, b, M[ 7], 14, 0x676f02d9);
769     R2(b, c, d, a, M[12], 20, 0x8d2a4c8a);
770 
771     R3(a, b, c, d, M[ 5],  4, 0xfffa3942);
772     R3(d, a, b, c, M[ 8], 11, 0x8771f681);
773     R3(c, d, a, b, M[11], 16, 0x6d9d6122);
774     R3(b, c, d, a, M[14], 23, 0xfde5380c);
775     R3(a, b, c, d, M[ 1],  4, 0xa4beea44);
776     R3(d, a, b, c, M[ 4], 11, 0x4bdecfa9);
777     R3(c, d, a, b, M[ 7], 16, 0xf6bb4b60);
778     R3(b, c, d, a, M[10], 23, 0xbebfbc70);
779     R3(a, b, c, d, M[13],  4, 0x289b7ec6);
780     R3(d, a, b, c, M[ 0], 11, 0xeaa127fa);
781     R3(c, d, a, b, M[ 3], 16, 0xd4ef3085);
782     R3(b, c, d, a, M[ 6], 23, 0x04881d05);
783     R3(a, b, c, d, M[ 9],  4, 0xd9d4d039);
784     R3(d, a, b, c, M[12], 11, 0xe6db99e5);
785     R3(c, d, a, b, M[15], 16, 0x1fa27cf8);
786     R3(b, c, d, a, M[ 2], 23, 0xc4ac5665);
787 
788     R4(a, b, c, d, M[ 0],  6, 0xf4292244);
789     R4(d, a, b, c, M[ 7], 10, 0x432aff97);
790     R4(c, d, a, b, M[14], 15, 0xab9423a7);
791     R4(b, c, d, a, M[ 5], 21, 0xfc93a039);
792     R4(a, b, c, d, M[12],  6, 0x655b59c3);
793     R4(d, a, b, c, M[ 3], 10, 0x8f0ccc92);
794     R4(c, d, a, b, M[10], 15, 0xffeff47d);
795     R4(b, c, d, a, M[ 1], 21, 0x85845dd1);
796     R4(a, b, c, d, M[ 8],  6, 0x6fa87e4f);
797     R4(d, a, b, c, M[15], 10, 0xfe2ce6e0);
798     R4(c, d, a, b, M[ 6], 15, 0xa3014314);
799     R4(b, c, d, a, M[13], 21, 0x4e0811a1);
800     R4(a, b, c, d, M[ 4],  6, 0xf7537e82);
801     R4(d, a, b, c, M[11], 10, 0xbd3af235);
802     R4(c, d, a, b, M[ 2], 15, 0x2ad7d2bb);
803     R4(b, c, d, a, M[ 9], 21, 0xeb86d391);
804 
805     ABCD[0] += a;
806     ABCD[1] += b;
807     ABCD[2] += c;
808     ABCD[3] += d;
809 }
810 
811 /*
812  * NAME:        kfun->hash_md5()
813  * DESCRIPTION: Compute MD5 message digest.  See "Applied Cryptography" by
814  *              Bruce Schneier, Second Edition, p. 436-441.
815  */
816 int kf_hash_md5(f, nargs)
817 register frame *f;
818 int nargs;
819 {
820     char buffer[64];
821     Uint cv[4];
822     register int i;
823     register ssizet len;
824     register unsigned short bufsz;
825     register char *p;
826     register Int cost;
827     register Uint length;
828 
829     cost = 3 * nargs + 64;
830     for (i = nargs; --i >= 0; ) {
831         cost += f->sp[i].u.string->len;
832     }
833     if (!f->rlim->noticks && f->rlim->ticks <= cost) {
834         f->rlim->ticks = 0;
835         error("Out of ticks");
836     }
837     i_add_ticks(f, cost);
838 
839     /*
840      * These constants must apparently be little-endianized, though AC2 does
841      * not explicitly say so.
842      */
843     cv[0] = 0x67452301;
844     cv[1] = 0xefcdab89;
845     cv[2] = 0x98badcfe;
846     cv[3] = 0x10325476;
847     length = 0;
848     bufsz = 0;
849 
850     for (i = nargs; --i >= 0; ) {
851         len = f->sp[i].u.string->len;
852         if (len != 0) {
853             length += len;
854             p = f->sp[i].u.string->text;
855             if (bufsz != 0) {
856                 register unsigned short size;
857 
858                 /* fill buffer and digest */
859                 size = 64 - bufsz;
860                 if (size > len) {
861                     size = len;
862                 }
863                 memcpy(buffer + bufsz, p, size);
864                 p += size;
865                 len -= size;
866                 bufsz += size;
867 
868                 if (bufsz == 64) {
869                     md5_block(cv, buffer);
870                     bufsz = 0;
871                 }
872             }
873 
874             while (len >= 64) {
875                 /* digest directly from string */
876                 md5_block(cv, p);
877                 p += 64;
878                 len -= 64;
879             }
880 
881             if (len != 0) {
882                 /* put remainder in buffer */
883                 memcpy(buffer, p, bufsz = len);
884             }
885         }
886         str_del(f->sp[i].u.string);
887     }
888 
889     /* append padding and digest final block(s) */
890     buffer[bufsz++] = 0x80;
891     if (bufsz > 56) {
892         memset(buffer + bufsz, '\0', 64 - bufsz);
893         md5_block(cv, buffer);
894         bufsz = 0;
895     }
896     memset(buffer + bufsz, '\0', 64 - bufsz);
897     buffer[56] = length << 3;
898     buffer[57] = length >> 5;
899     buffer[58] = length >> 13;
900     buffer[59] = length >> 21;
901     buffer[60] = length >> 29;
902     md5_block(cv, buffer);
903 
904     for (bufsz = i = 0; i < 4; bufsz += 4, i++) {
905         buffer[bufsz + 0] = cv[i];
906         buffer[bufsz + 1] = cv[i] >> 8;
907         buffer[bufsz + 2] = cv[i] >> 16;
908         buffer[bufsz + 3] = cv[i] >> 24;
909     }
910     f->sp += nargs - 1;
911     PUT_STR(f->sp, str_new(buffer, 16L));
912     return 0;
913 }
914 # endif
915 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.