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