/[pkg-mixmaster]/trunk/Mix/Src/buffers.c
ViewVC logotype

Contents of /trunk/Mix/Src/buffers.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 987 - (show annotations) (download)
Fri Mar 7 16:36:17 2008 UTC (5 years, 3 months ago) by colin
File MIME type: text/plain
File size: 15168 byte(s)
Fix use of NDEBUG and DEBUG
1 /* Mixmaster version 3.0 -- (C) 1999 - 2006 Anonymizer Inc. and others.
2
3 Mixmaster may be redistributed and modified under certain conditions.
4 This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
5 ANY KIND, either express or implied. See the file COPYRIGHT for
6 details.
7
8 Dynamically allocated buffers
9 $Id$ */
10
11
12 #include "mix3.h"
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <ctype.h>
17 #include <stdarg.h>
18 #ifdef WIN32
19 #include <io.h>
20 #endif /* WIN32 */
21 #include <assert.h>
22 #ifdef POSIX
23 #include <unistd.h>
24 #endif /* POSIX */
25
26 static void fail(void)
27 {
28 errlog(ERRORMSG, "Out of memory!\n");
29 abort();
30 }
31
32 #define space 128 /* allocate some additional space */
33
34 static void alloc(BUFFER *b)
35 {
36 b->data = malloc(space);
37 if (b->data == NULL)
38 fail();
39 b->data[0] = 0;
40 b->size = space;
41 }
42
43 #ifdef DEBUG
44 #undef buf_new
45 #endif /* DEBUG */
46
47 BUFFER *buf_new(void)
48 {
49 BUFFER *b;
50
51 b = malloc(sizeof(BUFFER));
52 if (b == NULL)
53 fail();
54 alloc(b);
55 b->length = 0;
56 b->ptr = 0;
57 b->sensitive = 0;
58
59 return (b);
60 }
61
62 static void sanity_check(BUFFER *b)
63 {
64 assert(b != NULL);
65 assert(b->size > 0);
66 assert(b->data != NULL);
67 assert(b->length >= 0 && b->length < b->size);
68 assert(b->ptr >= 0 && b->ptr <= b->length);
69 }
70
71 int buf_reset(BUFFER *buffer)
72 {
73 sanity_check(buffer);
74
75 buffer->length = 0;
76 buffer->ptr = 0;
77 if (buffer->sensitive)
78 memset(buffer->data, 0, buffer->size);
79 free(buffer->data);
80 alloc(buffer);
81 return (0);
82 }
83
84 int buf_free(BUFFER *buffer)
85 {
86 int err = 0;
87
88 if (buffer->sensitive)
89 memset(buffer->data, 0, buffer->size);
90 free(buffer->data);
91 free(buffer);
92 return (err);
93 }
94
95 int buf_clear(BUFFER *buffer)
96 {
97 sanity_check(buffer);
98 buffer->data[0] = '\0';
99 buffer->length = 0;
100 buffer->ptr = 0;
101 return (0);
102 }
103
104 int buf_append(BUFFER *buffer, byte *msg, int len)
105 {
106 assert(len >= 0);
107 sanity_check(buffer);
108
109 if (buffer->length + len >= buffer->size) {
110 register byte *new;
111 register long newsize;
112
113 newsize = 2 * buffer->length; /* double buffer size */
114 if (newsize < buffer->length + len + space)
115 newsize = buffer->length + len + space;
116 new = malloc(newsize);
117 if (new == NULL)
118 fail();
119 memcpy(new, buffer->data, buffer->length);
120 if (buffer->sensitive)
121 memset(buffer->data, 0, buffer->size);
122 free(buffer->data);
123 buffer->data = new;
124 buffer->size = newsize;
125 }
126 if (msg != NULL)
127 memcpy(buffer->data + buffer->length, msg, len);
128 buffer->length += len;
129
130 buffer->data[buffer->length] = 0;
131 return (0);
132 }
133
134 int buf_appendrnd(BUFFER *to, int n)
135 {
136 buf_append(to, NULL, n);
137 rnd_bytes(to->data + to->length - n, n);
138 return (0);
139 }
140
141 int buf_appendzero(BUFFER *to, int n)
142 {
143 buf_append(to, NULL, n);
144 memset(to->data + to->length - n, 0, n);
145 return (0);
146 }
147
148 int buf_setrnd(BUFFER *b, int n)
149 {
150 buf_prepare(b, n);
151 rnd_bytes(b->data, n);
152 return (0);
153 }
154
155 int buf_cat(BUFFER *to, BUFFER *from)
156 {
157 return (buf_append(to, from->data, from->length));
158 }
159
160 int buf_set(BUFFER *to, BUFFER *from)
161 {
162 buf_reset(to);
163 return (buf_cat(to, from));
164 }
165
166 int buf_appendc(BUFFER *to, byte b)
167 {
168 return (buf_append(to, &b, 1));
169 }
170
171 int buf_rest(BUFFER *to, BUFFER *from)
172 {
173 assert(from != to);
174 return (buf_append(to, from->data + from->ptr, from->length - from->ptr));
175 }
176
177 int buf_appends(BUFFER *buffer, char *s)
178 {
179 return (buf_append(buffer, s, strlen(s)));
180 }
181
182 int buf_sets(BUFFER *buffer, char *s)
183 {
184 buf_clear(buffer);
185 return (buf_appends(buffer, s));
186 }
187
188 int buf_setc(BUFFER *buffer, byte c)
189 {
190 buf_clear(buffer);
191 return (buf_appendc(buffer, c));
192 }
193
194 int buf_nl(BUFFER *b)
195 {
196 return (buf_append(b, "\n", 1));
197 }
198
199 int buf_vappendf(BUFFER *b, char *fmt, va_list args)
200 {
201 for (; *fmt != '\0'; fmt++)
202 if (*fmt == '%') {
203 int lzero = 0;
204 int longvar = 0;
205 int len = 0;
206
207 for (;;) {
208 if (*++fmt == '\0')
209 return (-1);
210 if (*fmt == '%') {
211 buf_appendc(b, '%');
212 break;
213 } else if (*fmt == 'b') { /* extension of printf */
214 buf_cat(b, va_arg(args, BUFFER *));
215
216 break;
217 } else if (*fmt == 'c') {
218 buf_appendc(b, va_arg(args, int));
219
220 break;
221 } else if (*fmt == 's') {
222 buf_appends(b, va_arg(args, char *));
223
224 break;
225 } else if (*fmt == 'd' || *fmt == 'X') {
226 int base, val, sign = 0;
227 BUFFER *out;
228
229 out = buf_new();
230 base = *fmt == 'd' ? 10 : 16;
231 if (longvar)
232 val = va_arg(args, long);
233
234 else
235 val = va_arg(args, int);
236
237 if (val < 0)
238 sign = 1, val = -val;
239 do {
240 if (val % base > 9)
241 buf_appendc(out, val % base - 10 + 'A');
242 else
243 buf_appendc(out, val % base + '0');
244 val /= base;
245 } while (val > 0);
246 if (sign)
247 len--;
248 while (len-- > out->length)
249 buf_appendc(b, lzero ? '0' : ' ');
250 if (sign)
251 buf_appendc(b, '-');
252 for (len = out->length - 1; len >= 0; len--)
253 buf_appendc(b, out->data[len]);
254 buf_free(out);
255 break;
256 } else if (*fmt == 'l')
257 longvar = 1;
258 else if (*fmt == '0' && len == 0)
259 lzero = 1;
260 else if (isdigit(*fmt))
261 len = len * 10 + *fmt - '0';
262 else
263 assert(0);
264 }
265 } else
266 buf_appendc(b, *fmt);
267 return (0);
268 }
269
270 int buf_setf(BUFFER *b, char *fmt, ...)
271 {
272 va_list args;
273 int ret;
274
275 va_start(args, fmt);
276 buf_clear(b);
277 ret = buf_vappendf(b, fmt, args);
278 va_end(args);
279 return (ret);
280 }
281
282 int buf_appendf(BUFFER *b, char *fmt, ...)
283 {
284 va_list args;
285 int ret;
286
287 va_start(args, fmt);
288 ret = buf_vappendf(b, fmt, args);
289 va_end(args);
290 return (ret);
291 }
292
293 int buf_pad(BUFFER *buffer, int size)
294 {
295 assert(size - buffer->length >= 0);
296 buf_appendrnd(buffer, size - buffer->length);
297 return (0);
298 }
299
300 int buf_prepare(BUFFER *buffer, int size)
301 {
302 buf_clear(buffer);
303 buf_append(buffer, NULL, size);
304 return (0);
305 }
306
307 int buf_read(BUFFER *outmsg, FILE *infile)
308 {
309 char buf[BUFSIZE];
310 int n;
311 int err = -1;
312
313 assert(infile != NULL);
314 sanity_check(outmsg);
315
316 for (;;) {
317 n = fread(buf, 1, BUFSIZE, infile);
318 if (n > 0)
319 err = 0;
320 buf_append(outmsg, buf, n);
321 if (n < BUFSIZE)
322 break;
323 #ifdef BUFFER_MAX
324 if (outmsg->length > BUFFER_MAX) {
325 errlog(ERRORMSG, "Message file too large. Giving up.\n");
326 return (1);
327 }
328 #endif /* BUFFER_MAX */
329 }
330
331 #ifdef WIN32
332 if (isatty(fileno(infile)) && isatty(fileno(stdout)))
333 printf("\n");
334 #endif /* WIN32 */
335
336 return (err);
337 }
338
339 int buf_write(BUFFER *buffer, FILE *out)
340 {
341 assert(out != NULL);
342 sanity_check(buffer);
343
344 return (fwrite(buffer->data, 1, buffer->length, out) == buffer->length
345 ? 0 : -1);
346 }
347
348 int buf_write_sync(BUFFER *buffer, FILE *out)
349 {
350 int ret = 0;
351
352 if (buf_write(buffer, out) == -1) {
353 fclose(out);
354 return -1;
355 }
356
357 if (fflush(out) != 0)
358 ret = -1;
359
360 #ifdef POSIX
361 /* dir entry not synced */
362 if (fsync(fileno(out)) != 0)
363 ret = -1;
364 #endif /* POSIX */
365
366 if (fclose(out) != 0)
367 ret = -1;
368
369 return ret;
370 }
371
372 int buf_rewind(BUFFER *buffer)
373 {
374 sanity_check(buffer);
375
376 buffer->ptr = 0;
377 return (0);
378 }
379
380 int buf_get(BUFFER *buffer, BUFFER *to, int n)
381 {
382 sanity_check(buffer);
383 sanity_check(to);
384 assert(n > 0);
385 assert(buffer != to);
386
387 buf_clear(to);
388 if (buffer->length - buffer->ptr < n)
389 return (-1);
390 buf_append(to, buffer->data + buffer->ptr, n);
391 buffer->ptr += n;
392 return (0);
393 }
394
395 int buf_getc(BUFFER *buffer)
396 {
397 sanity_check(buffer);
398 if (buffer->ptr == buffer->length)
399 return (-1);
400 else
401 return (buffer->data[buffer->ptr++]);
402 }
403
404 void buf_ungetc(BUFFER *buffer)
405 {
406 sanity_check(buffer);
407 if (buffer->ptr > 0)
408 buffer->ptr--;
409 }
410
411 int buf_getline(BUFFER *buffer, BUFFER *line)
412 {
413 register int i;
414 int ret = 0;
415 int nl = 0;
416
417 sanity_check(buffer);
418
419 if (line != NULL)
420 buf_clear(line);
421 if (buffer->ptr == buffer->length)
422 return (-1);
423
424 for (i = buffer->ptr; i < buffer->length; i++) {
425 if (buffer->data[i] > '\r')
426 continue;
427 if (buffer->data[i] == '\0' || buffer->data[i] == '\n') {
428 nl = 1;
429 break;
430 }
431 if (buffer->data[i] == '\r' &&
432 i + 1 <= buffer->length && buffer->data[i + 1] == '\n') {
433 nl = 2;
434 break;
435 }
436 }
437
438 if (line != NULL)
439 buf_append(line, buffer->data + buffer->ptr, i - buffer->ptr);
440 if (i == buffer->ptr)
441 ret = 1;
442 buffer->ptr = i + nl;
443
444 return (ret);
445 }
446
447 int buf_chop(BUFFER *b)
448 {
449 int i;
450
451 sanity_check(b);
452
453 for (i = 0; i < b->length; i++)
454 if (b->data[i] == '\0' || b->data[i] == '\n' ||
455 (b->data[i] == '\r' && i + 1 < b->length &&
456 b->data[i + 1] == '\n'))
457 b->length = i;
458 b->data[b->length] = 0;
459 return (0);
460 }
461
462 int buf_isheader(BUFFER *buffer)
463 {
464 BUFFER *line;
465 long p;
466 int i;
467 int err;
468 int ret;
469
470 line = buf_new();
471 p = buffer->ptr;
472 ret = 0;
473 err = buf_getline(buffer, line);
474 if (err != 0)
475 goto end;
476
477 for (i = 0; i < line->length; i++) {
478 if (line->data[i] == ' ' || line->data[i] == '\t')
479 break;
480 if (line->data[i] == ':') {
481 ret = 1;
482 break;
483 }
484 }
485
486 end:
487 buffer->ptr = p;
488 buf_free(line);
489 return(ret);
490 }
491
492 int buf_getheader(BUFFER *buffer, BUFFER *field, BUFFER *content)
493 {
494 BUFFER *line;
495 long p;
496 int i;
497 int err;
498
499 line = buf_new();
500 buf_reset(field);
501 buf_reset(content);
502
503 err = buf_getline(buffer, line);
504 if (err != 0)
505 goto end;
506
507 err = -1;
508 for (i = 0; i < line->length; i++) {
509 if (line->data[i] == ' ' || line->data[i] == '\t')
510 break;
511 if (line->data[i] == ':') {
512 err = 0;
513 break;
514 }
515 }
516 if (err == -1 && bufileft(line, "From ")) {
517 buf_set(field, line);
518 err = 0;
519 }
520 if (err == -1) {
521 /* badly formatted message -- try to process anyway */
522 buf_sets(field, "X-Invalid");
523 buf_set(content, line);
524 err = 0;
525 goto end;
526 }
527 buf_append(field, line->data, i);
528 if (i < line->length)
529 i++;
530 else
531 err = 1;
532 while (i < line->length &&
533 (line->data[i] == ' ' || line->data[i] == '\t'))
534 i++;
535 buf_append(content, line->data + i, line->length - i);
536
537 for (;;) {
538 p = buffer->ptr;
539 if (buf_getline(buffer, line) != 0)
540 break;
541 if (line->data[0] != ' ' && line->data[0] != '\t')
542 break;
543 #if 1
544 buf_nl(content);
545 buf_cat(content, line);
546 #else /* end of 1 */
547 buf_appendc(content, ' ');
548 buf_appends(content, line->data + 1);
549 #endif /* else if not 1 */
550 }
551 buffer->ptr = p;
552 end:
553 buf_free(line);
554 return (err);
555 }
556
557 int buf_appendheader(BUFFER *buffer, BUFFER *field, BUFFER *content)
558 {
559 return buf_appendf(buffer, "%b: %b\n", field, content);
560 }
561
562 int buf_lookahead(BUFFER *buffer, BUFFER *line)
563 {
564 long p;
565 int e;
566
567 p = buffer->ptr;
568 e = buf_getline(buffer, line);
569 buffer->ptr = p;
570 return (e);
571 }
572
573 int buf_eq(BUFFER *b1, BUFFER *b2)
574 {
575 sanity_check(b1);
576 sanity_check(b2);
577
578 if (b1->length != b2->length)
579 return (0);
580 if (b1->length > 0 && memcmp(b1->data, b2->data, b1->length) != 0)
581 return (0);
582 return (1);
583 }
584
585 int buf_ieq(BUFFER *b1, BUFFER *b2)
586 {
587 int i;
588 sanity_check(b1);
589 sanity_check(b2);
590
591 if (b1->length != b2->length)
592 return (0);
593 for (i = 0; i < b1->length; i++)
594 if (tolower(b1->data[i]) != tolower(b2->data[i]))
595 return (0);
596 return (1);
597 }
598
599 void buf_move(BUFFER *dest, BUFFER *src)
600 /* equivalent to buf_set(dest, src); buf_reset(src); */
601 {
602 BUFFER temp;
603 sanity_check(src);
604 buf_reset(dest);
605 temp.data = dest->data, temp.size = dest->size;
606 dest->data = src->data, dest->size = src->size, dest->length = src->length;
607 src->data = temp.data, src->size = temp.size, src->length = 0;
608 dest->ptr = 0, src->ptr = 0;
609 }
610
611 int buf_appendl(BUFFER *b, long l)
612 {
613 buf_appendc(b, (l >> 24) & 255);
614 buf_appendc(b, (l >> 16) & 255);
615 buf_appendc(b, (l >> 8) & 255);
616 buf_appendc(b, l & 255);
617 return (0);
618 }
619
620 int buf_appendl_lo(BUFFER *b, long l)
621 {
622 buf_appendc(b, l & 255);
623 buf_appendc(b, (l >> 8) & 255);
624 buf_appendc(b, (l >> 16) & 255);
625 buf_appendc(b, (l >> 24) & 255);
626 return (0);
627 }
628
629 long buf_getl(BUFFER *b)
630 {
631 long l;
632
633 if (b->ptr + 4 > b->length)
634 return (-1);
635 l = buf_getc(b) << 24;
636 l += buf_getc(b) << 16;
637 l += buf_getc(b) << 8;
638 l += buf_getc(b);
639 return (l);
640 }
641
642 long buf_getl_lo(BUFFER *b)
643 {
644 long l;
645
646 if (b->ptr + 4 > b->length)
647 return (-1);
648 l = buf_getc(b);
649 l += buf_getc(b) << 8;
650 l += buf_getc(b) << 16;
651 l += buf_getc(b) << 24;
652
653 return (l);
654 }
655
656 int buf_appendi(BUFFER *b, int i)
657 {
658 buf_appendc(b, (i >> 8) & 255);
659 buf_appendc(b, i & 255);
660 return (0);
661 }
662
663 int buf_appendi_lo(BUFFER *b, int i)
664 {
665 buf_appendc(b, i & 255);
666 buf_appendc(b, (i >> 8) & 255);
667 return (0);
668 }
669
670 int buf_geti(BUFFER *b)
671 {
672 int i;
673
674 if (b->ptr + 2 > b->length)
675 return (-1);
676 i = buf_getc(b) << 8;
677 i += buf_getc(b);
678 return (i);
679 }
680
681 int buf_geti_lo(BUFFER *b)
682 {
683 int i;
684
685 if (b->ptr + 2 > b->length)
686 return (-1);
687 i = buf_getc(b);
688 i += buf_getc(b) << 8;
689 return (i);
690 }
691
692 int buf_getb(BUFFER *b, BUFFER *p)
693 {
694 long l;
695
696 l = buf_getl(b);
697 return (buf_get(b, p, l));
698 }
699
700 int buf_appendb(BUFFER *b, BUFFER *p)
701 {
702 long l;
703
704 l = p->length;
705 buf_appendl(b, l);
706 return (buf_cat(b, p));
707 }
708
709 int bufleft(BUFFER *b, char *k) {
710 return(strleft(b->data, k));
711 }
712
713 int bufileft(BUFFER *b, char *k) {
714 return(strileft(b->data, k));
715 }
716
717 int buffind(BUFFER *b, char *k) {
718 return(strfind(b->data, k));
719 }
720
721 int bufifind(BUFFER *b, char *k) {
722 return(strifind(b->data, k));
723 }
724
725 int bufiright(BUFFER *b, char *k) {
726 int l = strlen(k);
727 if (l <= b->length)
728 return (strieq(b->data + b->length - l, k));
729 return(0);
730 }
731
732 int bufeq(BUFFER *b, char *k) {
733 return(streq(b->data, k));
734 }
735
736 int bufieq(BUFFER *b, char *k) {
737 return(strieq(b->data, k));
738 }
739
740 /* void buf_cut_out(BUFFER *buffer, BUFFER *cut_out, BUFFER *rest,
741 * int from, int len);
742 *
743 * Cut a chunk out of the buffer.
744 *
745 * Starting with from, len bytes are cut out of buffer. The chunk
746 * of text that has been cut out is returned in cut_out, the
747 * remainings of buffer are returned in rest.
748 *
749 * This function was added by Gerd Beuster. (gb@uni-koblenz.de)
750 */
751
752 void buf_cut_out(BUFFER *buffer, BUFFER *cut_out, BUFFER *rest,
753 int from, int len){
754
755 assert((len >= 0) && (from >= 0));
756 assert(from+len <= buffer->length);
757 assert(cut_out != rest);
758
759 buffer->ptr = 0;
760 if(from > 0)
761 buf_get(buffer, rest, from);
762 buf_get(buffer, cut_out, len);
763 buf_rest(rest, buffer);
764 }
765
766
767 #ifdef DEBUG
768 /* check for memory leaks */
769 #undef malloc
770 #undef free
771 void *malloc(size_t size);
772 void free(void *ptr);
773 #define max 100000
774 static int n=0;
775 static void *m[max];
776 static char *mm[max];
777
778 void mix3_leaks(void) {
779 int i, ok=1;
780 for (i = 0; i < n; i++)
781 if (m[i]) {
782 fprintf(stderr, "Leak [%d] %s\n", i, mm[i]);
783 ok = 0;
784 }
785 if (ok)
786 fprintf(stderr, "No memory leaks.\n");
787 }
788
789 void *mix3_malloc(size_t size) {
790 void *ptr;
791 if (n == 0)
792 atexit(mix3_leaks);
793 ptr = malloc(size);
794 if (n >= max) abort();
795 m[n++] = ptr;
796 mm[n] = "?";
797 return(ptr);
798 }
799
800 void mix3_free(void *ptr) {
801 int i;
802 for (i = 0; i < n; i++)
803 if (m[i] == ptr) {
804 m[i] = 0;
805 break;
806 }
807 free(ptr);
808 }
809
810 BUFFER *mix3_bufnew(char *file, int line, char *func) {
811 mm[n] = malloc(strlen(file) + strlen(func) + 15);
812 sprintf(mm[n], "in %s %s:%d", func, file, line);
813 return(buf_new());
814 }
815 #endif /* DEBUG */

Properties

Name Value
svn:keywords Id

  ViewVC Help
Powered by ViewVC 1.1.5